diff options
author | 2022-09-21 14:18:08 +0100 | |
---|---|---|
committer | 2022-10-02 04:31:25 +0100 | |
commit | a529111f77ff46f4836fe7312e70953bc16587cf (patch) | |
tree | 9dc3924cb1a6ef3ef853b7bb45f735365e0b4e6d /doc | |
parent | Import Ghostscript 9.56.1 (diff) | |
download | ghostscript-gpl-patches-ghostscript-10.tar.gz ghostscript-gpl-patches-ghostscript-10.tar.bz2 ghostscript-gpl-patches-ghostscript-10.zip |
Import Ghostscript 10.0ghostscript-10.0ghostscript-10
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'doc')
106 files changed, 29579 insertions, 47095 deletions
diff --git a/doc/API.htm b/doc/API.htm deleted file mode 100644 index 5c6f677a..00000000 --- a/doc/API.htm +++ /dev/null @@ -1,1756 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>The Ghostscript Interpreter Application Programming Interface (API)</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1>Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a> - </header> - <main> - - <article> - - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>API</h1> - -<h2><a name="toc"></a>Table of contents</h2> - -<ul class="toc"> - <li><a href="#API">What is the Ghostscript Interpreter API?</a></li> - <li><a href="#Exported_functions ">Exported functions</a></li> - <li> - <ul> - <li><a href="#revision"><code>gsapi_revision</code></a></li> - <li><a href="#new_instance"><code>gsapi_new_instance</code></a></li> - <li><a href="#delete_instance"><code>gsapi_delete_instance</code></a></li> - <li><a href="#set_stdio_with_handle"><code>gsapi_set_stdio_with_handle</code></a></li> - <li><a href="#set_stdio"><code>gsapi_set_stdio</code></a></li> - <li><a href="#set_poll_with_handle"><code>gsapi_set_poll_with_handle</code></a></li> - <li><a href="#set_poll"><code>gsapi_set_poll</code></a></li> - <li><a href="#set_display_callback"><code>gsapi_set_display_callback</code></a></li> - <li><a href="#register_callout"><code>gsapi_register_callout</code></a></li> - <li><a href="#deregister_callout"><code>gsapi_deregister_callout</code></a></li> - <li><a href="#set_arg_encoding"><code>gsapi_set_arg_encoding</code></a></li> - <li><a href="#get_default_device_list"><code>gsapi_get_default_device_list</code></a></li> - <li><a href="#set_default_device_list"><code>gsapi_set_default_device_list</code></a></li> - <li><a href="#run"><code>gsapi_run_string_begin</code></a></li> - <li><a href="#run"><code>gsapi_run_string_continue</code></a></li> - <li><a href="#run"><code>gsapi_run_string_end</code></a></li> - <li><a href="#run"><code>gsapi_run_string_with_length</code></a></li> - <li><a href="#run"><code>gsapi_run_string</code></a></li> - <li><a href="#run"><code>gsapi_run_file</code></a></li> - <li><a href="#init"><code>gsapi_init_with_args</code></a></li> - <li><a href="#exit"><code>gsapi_exit</code></a></li> - <li><a href="#set_param"><code>gsapi_set_param</code></a></li> - <li><a href="#get_param"><code>gsapi_get_param</code></a></li> - <li><a href="#enumerate_params"><code>gsapi_enumerate_params</code></a></li> - <li><a href="#add_control_path"><code>gsapi_add_control_path</code></a></li> - <li><a href="#remove_control_path"><code>gsapi_remove_control_path</code></a></li> - <li><a href="#purge_control_paths"><code>gsapi_purge_control_paths</code></a></li> - <li><a href="#activate_path_control"><code>gsapi_activate_path_control</code></a></li> - <li><a href="#is_path_control_active"><code>gsapi_is_path_control_active</code></a></li> - <li><a href="#add_fs"><code>gsapi_add_fs</code></a></li> - <li><a href="#remove_fs"><code>gsapi_remove_fs</code></a></li> - <li><a href="#return_codes">Return codes</a></li> - <li><a href="#gsapi_fs_t">gsapi_fs_t</a></li> - <li><a href="#callout">Callouts</a></li> - </ul> - </li> - <li><a href="#Example_usage">Example usage</a></li> - <li><a href="#stdio">Standard input and output</a></li> - <li><a href="#display">Display device</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript overview</a>.</p> - -<p> -<b>WARNING:</b> The API described in this document is subject to changes in -future releases, possibly ones that are not backward compatible with what -is described here.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - - -<h2><a name="API"></a>What is the Ghostscript Interpreter API?</h2> - -<p> -The Ghostscript interpreter can be built as a dynamic link library -(DLL) on Microsoft Windows, as a shared object on the -Linux, Unix and MacOS X platforms. With some changes, it could be built -as a static library. This document describes the Application Programming -Interface (API) for the Ghostscript interpreter library. -This should not be confused with the -<a href="Lib.htm">Ghostscript library</a> which provides a graphics -library but not the interpreter.</p> -<p> -This supercedes the old <a href="DLL.htm">DLL</a> interface.</p> -<p> -To provide the interface described in the -<a href="Use.htm">usage documentation</a>, a smaller independent -executable loads the DLL/shared object. -This executable must provide all the interaction with the windowing system, -including image windows and, if necessary, a text window.</p> - -<p> -The Ghostscript interpreter library's name and characteristics differ -for each platform:</p> - -<ul> -<li>The Win32 DLL <code>gsdll32.dll</code> -can be used by multiple programs simultaneously, but only once -within each process.</li> - -<li>The OS/2 DLL <code>gsdll2.dll</code> has -MULTIPLE NONSHARED data segments and can be called by multiple programs -simultaneously.</li> - -<li>The Linux shared object <code>libgs.so</code> -can be used by multiple programs simultaneously.</li> - </ul> -<p> -The source for the executable is in <code>dw</code>*.* (Windows), -<code>dp</code>*.* (OS/2) and <code>dx</code>*.* (Linux/Unix). -See these source files for examples of how to use the DLL.</p> - -<p> -The source file <tt>dxmainc.c</tt> can also serve as an example of how to use the -shared library component on MacOS X, providing the same command-line tool it does -on any linux, bsd or similar operating system.</p> -<p> -At this stage, Ghostscript does not support multiple instances -of the interpreter within a single process.</p> - -<hr> - -<h2><a name="Exported_functions"></a>Exported functions</h2> - -<p> -The functions exported by the DLL/shared object are described -in the header file <a href="../psi/iapi.h"><code>iapi.h</code></a> -and are summarised below. Omitted from the summary are -the calling convention (e.g. __stdcall), details of return -values and error handling.</p> - - -<ul> -<li><code> -int -<a href="#revision">gsapi_revision</a> -(gsapi_revision_t *pr, int len); -</code></li> - -<li><code> -int -<a href="#new_instance">gsapi_new_instance</a> -(void **pinstance, void *caller_handle); -</code></li> - -<li><code> -void -<a href="#delete_instance">gsapi_delete_instance</a> -(void *instance); -</code></li> - -<li><code> -int -<a href="#set_stdio_with_handle">gsapi_set_stdio_with_handle</a> -(void *instance, - int(*stdin_fn)(void *caller_handle, char *buf, int len), - int(*stdout_fn)(void *caller_handle, const char *str, int len), - int(*stderr_fn)(void *caller_handle, const char *str, int len), - void *caller_handle); -</code></li> - -<li><code> -int -<a href="#set_stdio">gsapi_set_stdio</a> -(void *instance, - int(*stdin_fn)(void *caller_handle, char *buf, int len), - int(*stdout_fn)(void *caller_handle, const char *str, int len), - int(*stderr_fn)(void *caller_handle, const char *str, int len)); -</code></li> - -<li><code> -int -<a href="#set_poll_with_handle">gsapi_set_poll_with_handle</a> -(void *instance, int(*poll_fn)(void *caller_handle), void *caller_handle); -</code></li> - -<li><code> -int -<a href="#set_poll">gsapi_set_poll</a> -(void *instance, int(*poll_fn)(void *caller_handle)); -</code></li> - -<li><code> -int -<a href="#set_display_callback">gsapi_set_display_callback</a> -(void *instance, display_callback *callback); -</code></li> - -<li><code> -int -<a href="#register_callout">gsapi_register_callout</a> -(void *instance, gs_callout callout, void *callout_handle); -</code></li> - -<li><code> -void -<a href="#deregister_callout">gsapi_deregister_callout</a> -(void *instance, gs_callout callout, void *callout_handle); -</code></li> - -<li><code> -int -<a href="#set_arg_encoding">gsapi_set_arg_encoding</a> -(void *instance, int encoding); -</code></li> - -<li><code> -int -<a href="#get_default_device_list">gsapi_get_default_device_list</a>(void *instance, char **list, int *listlen); -</code></li> - -<li><code> -int -<a href="#set_default_device_list">gsapi_set_default_device_list</a>(void *instance, const char *list, int listlen); -</code></li> - -<li><code> -int -<a href="#run">gsapi_run_string_begin</a> -(void *instance, int user_errors, int *pexit_code); -</code></li> - -<li><code> -int -<a href="#run">gsapi_run_string_continue</a> -(void *instance, - const char *str, unsigned int length, int user_errors, int *pexit_code); -</code></li> - -<li><code> -int -<a href="#run">gsapi_run_string_end</a> -(void *instance, int user_errors, int *pexit_code); -</code></li> - -<li><code> -int -<a href="#run">gsapi_run_string_with_length</a> -(void *instance, - const char *str, unsigned int length, int user_errors, int *pexit_code); -</code></li> - -<li><code> -int -<a href="#run">gsapi_run_string</a> -(void *instance, - const char *str, int user_errors, int *pexit_code); -</code></li> - -<li><code> -int -<a href="#run">gsapi_run_file</a> -(void *instance, - const char *file_name, int user_errors, int *pexit_code); -</code></li> - -<li><code> -int -<a href="#init">gsapi_init_with_args</a> -(void *instance, int argc, char **argv); -</code></li> - -<li><code> -int -<a href="#exit">gsapi_exit</a> -(void *instance); -</code></li> - -<li><code> -int -<a href="#set_param">gsapi_set_param</a>(void *instance, const char *param, const void *value, gs_set_param_type type); -</code></li> - -<li><code> - int - <a href="#get_param">gsapi_get_param</a>(void *instance, const char *param, void *value, gs_set_param_type type); -</code></li> - -<li><code> -int -<a href="#enumerate_params">gsapi_enumerate_params</a>(void *instance, void **iter, const char **key, gs_set_param_type *type); -</code></li> - -<li><code> -int -<a href="#add_control_path">gsapi_add_control_path</a>(void *instance, int type, const char *path); -</code></li> - -<li><code> -int -<a href="#remove_control_path">gsapi_remove_control_path</a>(void *instance, int type, const char *path); -</code></li> - -<li><code> -void -<a href="#purge_control_paths">gsapi_purge_control_paths</a>(void *instance, int type); -</code></li> - -<li><code> -void -<a href="#activate_path_control">gsapi_activate_path_control</a>(void *instance, int enable); -</code></li> - -<li><code> -int -<a href="#is_path_control_active">gsapi_is_path_control_active</a>(void *instance); -</code></li> - -<li><code> -int -<a href="#add_fs">gsapi_add_fs</a> -(void *instance, - gsapi_fs_t *fs, void *secret); -</code></li> - -<li><code> -void -<a href="#remove_fs">gsapi_remove_fs</a> -(void *instance, - gsapi_fs_t *fs, void *secret); -</code></li> - -</ul> - -<h3><a name="revision"></a><code>gsapi_revision()</code></h3> - -<blockquote> -This function returns the revision numbers and strings of the Ghostscript -interpreter library; you should call it before any other interpreter -library functions to make sure that the correct version of the -Ghostscript interpreter has been loaded. - -<blockquote> -<pre> -typedef struct gsapi_revision_s { - const char *product; - const char *copyright; - long revision; - long revisiondate; -} gsapi_revision_t; -gsapi_revision_t r; - -if (gsapi_revision(&r, sizeof(r)) == 0) { - if (r.revision < 650) - printf("Need at least Ghostscript 6.50"); -} -else { - printf("revision structure size is incorrect"); -} -</pre></blockquote> -</blockquote> - - -<h3><a name="new_instance"></a><code>gsapi_new_instance()</code></h3> -<blockquote> -Create a new instance of Ghostscript. -This instance is passed to most other gsapi functions. -The caller_handle is the default value that will be provided to callback functions. - -<b>On some platforms (those that do not support threading), only one -instance of Ghostscript is supported at a time; any attempt to create -more than one at a time would result in gsapi_new_instance -returning an error.</p> - -<p>While the core Ghostscript devices are believed to be thread safe -now, a handful of devices are known not to be (at least the x11 devices, -uniprint, and the open printing devices). A new mechanism has been -implemented that allows devices to check for concurrent use and to -refuse to start up. The devices shipped with Ghostscript known to use -global variables have had these calls added to them. Any authors of -non-standard Ghostscript devices that use global variables should -consider adding the same calls to their own code.</p> -<p> -The first parameter, is a pointer to an opaque pointer ("<code>void **</code>"). -The opaque pointer ("<code>void *</code>") must be initialised to <code>NULL</code> before -the call to <code>gsapi_new_instance()</code>. See <a href="#Example_1">Example 1</a>. -</blockquote> - - -<h3><a name="delete_instance"></a><code>gsapi_delete_instance()</code></h3> -<blockquote> -Destroy an instance of Ghostscript. -Before you call this, Ghostscript must have finished. -If Ghostscript has been initialised, you must call -<code>gsapi_exit</code> before <code>gsapi_delete_instance</code>. -</blockquote> - - -<h3><a name="set_stdio_with_handle"></a><code>gsapi_set_stdio_with_handle()</code></h3> -<blockquote> -<p>Set the callback functions for stdio, together with the -handle to use in the callback functions. -The stdin callback function should return the number of -characters read, 0 for EOF, or -1 for error. -The stdout and stderr callback functions should return -the number of characters written. -<p><b>NOTE:</b> These callbacks do not affect output device I/O when -using "<code>%stdout</code>" as the output file. In that -case, device output will still be directed to the process "stdout" -file descriptor, not to the stdio callback. -</blockquote> - -<h3><a name="set_stdio"></a><code>gsapi_set_stdio()</code></h3> -<blockquote> -<p>Set the callback functions for stdio. The handle used -in the callbacks will be taken from the value passed -to <code><a href="#new_instance">gsapi_new_instance</a></code>. Otherwise the behaviour of this -function matches <code><a href="#set_stdio_with_handle">gsapi_set_stdio_with_handle</a></code>. -</blockquote> - - -<h3><a name="set_poll_with_handle"></a><code>gsapi_set_poll_with_handle()</code></h3> -<blockquote> -Set the callback function for polling, together with the handle to pass -to the callback function. This function will only be called if -the Ghostscript interpreter was compiled with <code>CHECK_INTERRUPTS</code> -as described in <code><a href="../base/gpcheck.h">gpcheck.h</a></code>. -<p> -The polling function should return zero if all is well, and return -negative if it wants ghostscript to abort. This is often -used for checking for a user cancel. This can also be used for -handling window events or cooperative multitasking.</p> -<p> -The polling function is called very frequently during interpretation and -rendering so it must be fast. If the function is slow, then using a counter -to return 0 immediately some number of times can be used to reduce the -performance impact.</p> -</blockquote> - -<h3><a name="set_poll"></a><code>gsapi_set_poll()</code></h3> -<blockquote> -Set the callback function for polling. The handle passed to the -callback function will be taken from the handle passed to -<code><a href="#new_instance">gsapi_new_instance</a></code>. -Otherwise the behaviour of this function matches -<code><a href="#set_poll_with_handle">gsapi_set_poll_with_handle</a></code>. -</blockquote> - -<h3><a name="set_display_callback"></a><code>gsapi_set_display_callback()</code></h3> -<blockquote> -<b>This call is deprecated; please use -<code><a href="#register_callout">gsapi_register_callout</a></code> -to register a <a href="#callout">callout</a> handler for the -<a href="#display">display</a> device in preference.</b> -Set the callback structure for the <a href="#display">display</a> -device. The handle passed in the callback functions is taken from -the <code>DisplayHandle</code> parameter (or NULL if there is no -such parameter). If the <a href="#display">display</a> device is used, -this must be called after -<code>gsapi_new_instance()</code> -and before <code>gsapi_init_with_args()</code>. -See <code><a href="../devices/gdevdsp.h">gdevdsp.h</a></code> -for more details. -</blockquote> - -<h3><a name="register_callout"></a><code>gsapi_register_callout()</code></h3> -<blockquote> -<p>This call registers a <code><a href="#callout">callout</a></code> -handler.</p> -</blockquote> - -<h3><a name="deregister_callout"></a><code>gsapi_deregister_callout()</code></h3> -<blockquote> -<p>This call deregisters a <code><a href="#callout">callout</a></code> handler -previously registered with <code><a href="#register_callout">gsapi_register_callout</a></code>. -All three arguments must match exactly for the callout handler to -be deregistered.</p> -</blockquote> - -<h3><a name="set_arg_encoding"></a><code>gsapi_set_arg_encoding()</code></h3> -<blockquote> -Set the encoding used for the interpretation of all subsequent args -supplied via the gsapi interface on this instance. By default we -expect args to be in encoding 0 (the 'local' encoding for this OS). -On Windows this means "the currently selected codepage". On Linux this -typically means utf8. This means that omitting to call this function -will leave Ghostscript running exactly as it always has. Please note -that use of the 'local' encoding is now deprecated and should be -avoided in new code. -This must be called after <code>gsapi_new_instance()</code> -and before <code>gsapi_init_with_args()</code>. -</blockquote> - -<h3><a name="set_default_device_list"></a><code>set_default_device_list()</code></h3> -<blockquote> -Set the string containing the list of default device names, -for example "display x11alpha x11 bbox". Allows the calling -application to influence which device(s) gs will try, in order, -in it's selection of the default device. -This must be called after <code>gsapi_new_instance()</code> -and before <code>gsapi_init_with_args()</code>. -</blockquote> - -<h3><a name="get_default_device_list"></a><code>get_default_device_list()</code></h3> -<blockquote> -Returns a pointer to the current default device string. -This must be called after <code>gsapi_new_instance()</code> -and before <code>gsapi_init_with_args()</code>. -</blockquote> - -<h3><a name="init"></a><code>gsapi_init_with_args()</code></h3> -<blockquote> -Initialise the interpreter. -This calls <code>gs_main_init_with_args()</code> in -<code><a href="../psi/imainarg.c">imainarg.c</a></code>. -See below for <a href="#return_codes">return codes</a>. -The arguments are the same as the "C" main function: -argv[0] is ignored and the user supplied arguments -are argv[1] to argv[argc-1]. -</blockquote> - -<h3><a name="run"></a><code>gsapi_run_*()</code></h3> -<blockquote> -The <code>gsapi_run_*</code> functions are like -<code>gs_main_run_*</code> except that the error_object is omitted. -If these functions return <= -100, either quit or a fatal -error has occured. You must call <code>gsapi_exit()</code> next. -The only exception is <code>gsapi_run_string_continue()</code> -which will return <code>gs_error_NeedInput</code> if all is well. -See below for <a href="#return_codes">return codes</a>. -<p> -The address passed in <code>pexit_code</code> will be used to return the -exit code for the interpreter in case of a quit or fatal error. The -<code>user_errors</code> argument is normally set to zero to indicate that -errors should be handled through the normal mechanisms within the -interpreted code. If set to a negative value, the functions will return -an error code directly to the caller, bypassing the interpreted -language. The interpreted language's error handler is bypassed, regardless of -<code>user_errors</code> parameter, for the <code>gs_error_interrupt</code> -generated when <a href="#set_poll">the polling callback</a> returns a negative -value. A positive <code>user_errors</code> is treated the same as zero.</p> -<p> -There is a 64 KB length limit on any buffer submitted to a -<code>gsapi_run_*</code> function for processing. If you have more -than 65535 bytes of input then you must split it into smaller -pieces and submit each in a separate -<code>gsapi_run_string_continue()</code> call.</p> -</blockquote> - -<h3><a name="exit"></a><code>gsapi_exit()</code></h3> -<blockquote> -Exit the interpreter. -This must be called on shutdown if <code>gsapi_init_with_args()</code> -has been called, and just before <code>gsapi_delete_instance()</code>. -</blockquote> - -<h3><a name="set_param"></a><code>gsapi_set_param()</code></h3> -<blockquote> -Set a parameter. -Broadly, this is equivalent to setting a parameter using <code>-d</code>, <code>-s</code> or <code>-p</code> on the command line. This call cannot be made during a <code>run_string</code> operation. -<p> -Parameters in this context are not the same as 'arguments' as processed by <code>gsapi_init_with_args</code>, but often the same thing can be achieved. For example, with <code>gsapi_init_with_args</code>, we can pass "<code>-r200</code>" to change the resolution. Broadly the same thing can be achieved by using <code>gsapi_set_param</code> to set a parsed value of "<code><</HWResolution [ 200.0 200.0 ]>></code>". -<p> -Note, that internally, when we set a parameter, we perform an <code>initgraphics</code> operation. This means that using <code>set_param</code> other than at the start of a page is likely to give unexpected results. -<p>Further, note that attempting to set a parameter that the device does not recognise will be silently ignored, and that parameter will not be found in subsequent <code>gsapi_get_param</code> calls. -<p>The <code>type</code> argument dictates the kind of object that <code>value</code> points to: -<pre><code>typedef enum { - gs_spt_invalid = -1, - gs_spt_null = 0, /* void * is NULL */ - gs_spt_bool = 1, /* void * is a pointer to an int (0 false, - * non-zero true). */ - gs_spt_int = 2, /* void * is a pointer to an int */ - gs_spt_float = 3, /* void * is a float * */ - gs_spt_name = 4, /* void * is a char * */ - gs_spt_string = 5, /* void * is a char * */ - gs_spt_long = 6, /* void * is a long * */ - gs_spt_i64 = 7, /* void * is an int64_t * */ - gs_spt_size_t = 8, /* void * is a size_t * */ - gs_spt_parsed = 9, /* void * is a pointer to a char * to be parsed */ - - /* Setting a typed param causes it to be instantly fed to to the - * device. This can cause the device to reinitialise itself. Hence, - * setting a sequence of typed params can cause the device to reset - * itself several times. Accordingly, if you OR the type with - * gs_spt_more_to_come, the param will held ready to be passed into - * the device, and will only actually be sent when the next typed - * param is set without this flag (or on device init). Not valid - * for get_typed_param. */ - gs_spt_more_to_come = 1<<31 -} gs_set_param_type; -</code></pre> -<p>Combining a type value by ORRing it with the <code>gs_spt_more_to_come</code> flag will cause the <code>set_param</code> operation to be queued internally, but not actually be sent to the device. Thus a series of <code>set_param</code> operations can be queued, for example as below: -<pre> - int code = gsapi_set_param(instance, - "HWResolution", - "[300 300]", - gs_spt_parsed | gs_spt_more_to_come); - if (code >= 0) { - int i = 1; - code = gsapi_set_param(instance, - "FirstPage", - &i, - gs_spt_int | gs_spt_more_to_come); - } - if (code >= 0) { - int i = 3; - code = gsapi_set_param(instance, - "DownScaleFactor", - &i, - gs_spt_int); - } -</pre> -<p>This enables a series of set operations to be performed 'atomically'. This can be useful for performance, in that any reconfigurations to the device (such as page size changes or memory reallocations) will only happen when all the parameters are sent, rather than potentially each time each one is sent. -</blockquote> - -<h3><a name="get_param"></a><code>gsapi_get_param()</code></h3> -<blockquote> -Get a parameter. -Retrieve the current value of a parameter. -<p>If an error occurs, the return value is negative. Otherwise the return value is the number of bytes required for storage of the value. Call once with <code>value = NULL</code> to get the number of bytes required, then call again with <code>value</code> pointing to at least the required number of bytes where the value will be copied out. Note that the caller is required to know the type of value in order to get it. For all types other than <code>string</code>, <code>name</code>, and <code>parsed</code> knowing the type means you already know the size required. -<p> -This call retrieves parameters/values that have made it to the device. Thus, any values set using the <code>gs_spt_more_to_come</code> without a following call without that flag will not be retrieved. Similarly, attempting to get a parameter before <code>gsapi_init_with_args</code> has been called will not list any, even if <code>gsapi_set_param</code> has been used. -<p> -Attempting to read a parameter that is not set will return <code>gs_error_undefined (-21)</code>. Note that calling <code>gsapi_set_param</code> followed by <code>gsapi_get_param</code> may not find the value, if the device did not recognise the key as being one of its configuration keys. -</blockquote> - -<h3><a name="enumerate_params"></a><code>gsapi_enumerate_params()</code></h3> -<blockquote> -Enumerate the current parameters. -Call repeatedly to list out the current parameters. -<p> - The first call should have <code>*iter = NULL</code>. Subsequent calls should pass the same pointer in so the iterator can be updated. Negative return codes indicate error, 0 success, and 1 indicates that there are no more keys to read. On success, <code>key</code> will be updated to point to a null terminated string with the key name that is guaranteed to be valid until the next call to <code>gsapi_enumerate_params</code>. If <code>type</code> is non <code>NULL</code> then <code>*type</code> will be updated to have the type of the parameter. -<p> -Note that only one enumeration can happen at a time. Starting a second enumeration will reset the first. -<p> -The enumeration only returns parameters/values that have made it to the device. Thus, any values set using the <code>gs_spt_more_to_come</code> without a following call without that flag will not be retrieved. Similarly, attempting to enumerate parameters before <code>gsapi_init_with_args</code> has been called will not list any, even if <code>gsapi_set_param</code> has been used. -</blockquote> - -<h3><a name="add_control_path"></a><code>gsapi_add_control_path()</code></h3> -<blockquote> -Add a (case sensitive) path to one of the lists of permitted paths for file access. -See <a href="Use.htm#Safer">here</a> for more information about permitted paths. -</blockquote> - -<h3><a name="remove_control_path"></a><code>gsapi_remove_control_path()</code></h3> -<blockquote> -Remove a (case sensitive) path from one of the lists of permitted paths for file access. -See <a href="Use.htm#Safer">here</a> for more information about permitted paths. -</blockquote> - -<h3><a name="purge_control_paths"></a><code>gsapi_purge_control_paths()</code></h3> -<blockquote> -Clear all the paths from one of the lists of permitted paths for file access. -See <a href="Use.htm#Safer">here</a> for more information about permitted paths. -</blockquote> - -<h3><a name="activate_path_control"></a><code>gsapi_activate_path_control()</code></h3> -<blockquote> -Enable/Disable path control (i.e. whether paths are checked against permitted paths -before access is granted). -See <a href="Use.htm#Safer">here</a> for more information about permitted paths. -</blockquote> - -<h3><a name="is_path_control_active"></a><code>gsapi_is_path_control_active()</code></h3> -<blockquote> -Query whether path control is activated or not. -See <a href="Use.htm#Safer">here</a> for more information about permitted paths. -</blockquote> - -<h3><a name="add_fs"></a><code>gsapi_add_fs()</code></h3> -<blockquote> -Adds a new 'Filing System' to the interpreter. -This enables callers to implement their own filing systems. The system -starts with just the conventional 'file' handlers installed, to allow -access to the local filing system. Whenever files are to be opened -from the interpreter, the file paths are offered around each registered -filing system in turn (from most recently registered to oldest), until -either an error is given, or the file is opened successfully. -<p> -Details of the <code>gsapi_fs_t</code> are given -<a href="#gsapi_fs_t">below</a>. -</blockquote> - -<h3><a name="remove_fs"></a><code>gsapi_remove_fs()</code></h3> -<blockquote> -Remove a previously registered 'Filing System' from the interpreter. -Both the function pointers within the <code>gs_fs_t</code> and the -secret value must match exactly. -<p> -</blockquote> - -<h3><a name="return_codes"></a>Return codes</h3> - -<p> -The <code>gsapi_init_with_args</code>, <code>gsapi_run_*</code> and -<code>gsapi_exit</code> functions return an integer code.</p> - -<table> -<tr> - <th colspan="3">Return Codes from gsapi_*()</th> -</tr> -<tr> - <th>CODE</th> - <th colspan="2">STATUS</th> -</tr> -<tr> - <td>0</td> - <td colspan="2">No errors</td> -</tr> -<tr> - <td>gs_error_Quit</td> - <td colspan="2">"<code>quit</code>" has been executed. This is not an error. <code>gsapi_exit()</code> must be called next.</td> -</tr> -<tr> - <td>gs_error_interrupt</td> - <td colspan="2"><a href="#set_poll">The polling callback function</a> returned a negative value, requesting Ghostscript to abort.</td> -</tr> -<tr> - <td>gs_error_NeedInput</td> - <td colspan="2">More input is needed by <code>gsapi_run_string_continue()</code>. This is not an error.</td> -</tr> -<tr> - <td>gs_error_Info</td> - <td colspan="2">"<code>gs -h</code>" has been executed. This is not an error. <code>gsapi_exit()</code> must be called next.</td> -</tr> -<tr> - <td>< 0</td> - <td colspan="2">Error</td> -</tr> -<tr> - <td><= gs_error_Fatal</td> - <td colspan="2">Fatal error. <code>gsapi_exit()</code> must be called next.</td> -</tr> -</table> - -<p> -The <code>gsapi_run_*()</code> functions do not flush stdio. -If you want to see output from Ghostscript you -must do this explicitly as shown in the example below.</p> - -<p> -When executing a string with <code>gsapi_run_string_*()</code>, -<code>currentfile</code> is the input from the string. -Reading from <code>%stdin</code> uses the stdin callback.</p> - -<h3><a name="gsapi_fs_t"></a>gsapi_fs_t</h3> -<p>Each 'filing system' within gs is a structure of function -pointers; each function pointer gives a handler from taking a -different named resource (a file, a pipe, a printer, a scratch -file etc) and attempts to open it. - -<pre> -typedef struct -{ - int (*open_file)(const gs_memory_t *mem, - void *secret, - const char *fname, - const char *mode, - gp_file **file); - int (*open_pipe)(const gs_memory_t *mem, - void *secret, - const char *fname, - char *rfname, /* 4096 bytes */ - const char *mode, - gp_file **file); - int (*open_scratch)(const gs_memory_t *mem, - void *secret, - const char *prefix, - char *rfname, /* 4096 bytes */ - const char *mode, - int rm, - gp_file **file); - int (*open_printer)(const gs_memory_t *mem, - void *secret, - char *fname, /* 4096 bytes */ - int binary, - gp_file **file); - int (*open_handle)(const gs_memory_t *mem, - void *secret, - char *fname, /* 4096 bytes */ - const char *mode, - gp_file **file); -} gsapi_fs_t; -</pre> -<p>If the filename (always given in utf-8 format) is recognised as -being one that the filing system handles (perhaps by the prefix used), -then it should open the file, fill in the <code>gp_file</code> -pointer and return 0. -<p>If the filename is not-recognised as being one that the filing -system handles, then returning 0 will cause the filename to be -offered to other registered filing systems. -<p>If an error is returned (perhaps gs_error_invalidfileaccess), -then no other filing system will be allowed to try to open the -file. This provides a mechanism whereby a caller to gsapi can -completely control access to all files accessed via <code>gp_fopen</code> -at runtime. -<p>Note, that while most file access within ghostscript will be -redirected via these functions, stdio will not; see the existing -mechanisms within Ghostscript for intercepting/replacing this. -<ul> -<li>The <code>open_file</code> function pointer will be called when -something (most often a call to <code>gp_fopen</code>) attempts to -open a file. -<li>The <code>open_pipe</code> function pointer will be called when -something (most often a call to <code>gp_popen</code>) attempts to -open a pipe. <code>rfname</code> points to a 4K buffer in which the -actual name of the opened pipe should be returned. -<li>The <code>open_scratch</code> function pointer will be called when -something (most often a call to <code>gp_open_scratch_file</code> or -<code>gp_open_scratch_file_rm</code>) attempts to open a temporary file. -<code>rfname</code> points to a 4K buffer in which the actual name of -the opened pipe should be returned. If <code>rm</code> is true, then -the file should be set to delete itself when all handles to it are closed. -<li>The <code>open_printer</code> function pointer will be called when -something (most often a call to <code>gp_open_printer</code>) attempts -to open a stream to a printer. If <code>binary</code> is true, then -the stream should be opened as binary; most streams will be binary by -default - this has historical meaning on OS/2. -<li>The <code>open_handle</code> function pointer will be called when -something (most often a call via the postscript <code>%handle%</code> -IO device) attempts to open a Windows handle. This entry point will -never be called on non-Windows builds. -</ul> -<p>Any of these which are left as NULL will never be called; a filing -system with all of the entries left as NULL is therefore pointless. -<p>The most complex part of the implementation of these functions -is the creation of a <code>gp_file</code> instance to return. There are -some helper functions for this, best explained by example. -<p>Let us consider a hypothetical filing system that encrypts data as -it is written, and decrypts it as it is read back. As each file is -read and written the encryption/decryption routines will need to use -some state, carried between calls to the filing system. We therefore -might define a new type 'derived' from <code>gp_file</code> as follows: - -<pre> -typedef struct -{ - gp_file base; - /* State private to the implementation of this file for encryption/decryption */ - /* For example: */ - int foo; - char *bar; -} gp_file_crypt; -</pre> - -<p>An implementation of <code>gs_fs_t</code> for our 'crypt' filing system -might then look like this: - -<pre> -gsapi_fs_t gs_fs_crypt = -{ - crypt_open_file, - NULL, /* open_pipe */ - NULL, /* open_scratch */ - NULL, /* open_printer */ - NULL /* open_handle */ -}; -</pre> - -<p>In the above definition, we define a single handler, to cope with the -opening of our input/output files. If we wanted to encrypt/decrypt -other files too (perhaps the temporary files we produce) we'd need to -define additional handlers (such as <code>open_scratch</code>). - -<p>Our handler might look as follows: -<pre> -int crypt_open_file(const gs_memory_t *mem, - void *secret, - const char *filename, - const char *mode, - gp_file **file) -{ - gp_file_crypt crypt; - - /* Ignore any filename not starting with "crypt://" */ - if (strncmp(filename, "crypt://", 8) != 0) - return 0; - - /* Allocate us an instance (and fill in the non-crypt-specific - * internals) */ - crypt = (gp_file_crypt *)gp_file_alloc(mem, &crypt_ops, sizeof(*crypt), "gp_file_crypt"); - if (crypt == NULL) - return gs_error_VMerror; /* Allocation failed */ - - /* Setup the crypt-specific state */ - crypt->foo = 1; - crypt->bar = gs_alloc_bytes(mem->non_gc_memory, 256, "bar"); - /* If allocations fail, we need to clean up before exiting */ - if (crypt->bar) { - gp_file_dealloc(crypt); - return gs_error_VMerror; - } - - /* Return the new instance */ - *file = &crypt.base; - return 0; -} -</pre> - -<p>The crucial part of this function is the definition of <code>crypt_ops</code>, -an instance of the <code>gp_file_ops_t</code> type; a table of function pointers -that implement the actual operations required. - -<pre> -typedef struct { - int (*close)(gp_file *); - int (*getc)(gp_file *); - int (*putc)(gp_file *, int); - int (*read)(gp_file *, size_t size, unsigned int count, void *buf); - int (*write)(gp_file *, size_t size, unsigned int count, const void *buf); - int (*seek)(gp_file *, gs_offset_t offset, int whence); - gs_offset_t (*tell)(gp_file *); - int (*eof)(gp_file *); - gp_file *(*dup)(gp_file *, const char *mode); - int (*seekable)(gp_file *); - int (*pread)(gp_file *, size_t count, gs_offset_t offset, void *buf); - int (*pwrite)(gp_file *, size_t count, gs_offset_t offset, const void *buf); - int (*is_char_buffered)(gp_file *file); - void (*fflush)(gp_file *file); - int (*ferror)(gp_file *file); - FILE *(*get_file)(gp_file *file); - void (*clearerr)(gp_file *file); - gp_file *(*reopen)(gp_file *f, const char *fname, const char *mode); -} gp_file_ops_t; -</pre> - -<p>These functions generally follow the same patterns as the posix functions that match them, -and so in many cases we will describe these with references to such. -Whenever these routines are called, they will be passed a <code>gp_file</code> pointer. -This pointer will have originated from the <code>crypt_open_file</code> call, and so can -safely be cast back to a <code>gp_file_crypt</code> pointer to allow private data to be accessed. - -<dl> -<dt><code>close(gp_file *)</code> -<dd>close the given file; free any storage in the crypt specific parts of <code>gp_file_crypt</code>, -but not the gp_file_crypt structure itself. - -<dt><code>int getc(gp_file *)</code> -<dd>Get a single character from the file, returning it as an int (or -1 for EOF). -Behaves like <code>fgetc(FILE *)</code>. - -<dt><code>int putc(gp_file *, int)</code> -<dd>Put a single character to the file, returning the character on success, or -EOF (and setting the error indicator) on error. -Behaves like <code>fgetc(FILE *)</code>. - -<dt><code>int read(gp_file *, size_t size, unsigned int count, void *buf)</code> -<dd>Reads count entries of size bytes the file into buf, returning the number -of entries read. Behaves like <code>fread(FILE *, size, count, buf)</code>. - -<dt><code>int write(gp_file *, size_t size, unsigned int count, const void *buf)</code> -<dd>Writes count entries of size bytes from buf into the file, returning the -number of entries written. Behaves like <code>fwrite(FILE *, size, count, buf)</code>. - -<dt><code>int seek(gp_file *, gs_offset_t offset, int whence)</code> -<dd>Seeks within the file. Behaves like <code>fseek(FILE *, offset, whence)</code>. - -<dt><code>gs_offset_t tell(gp_file *)</code> -<dd>Returns the current offset within the file. Behaves like <code>ftell(FILE *)</code>. - -<dt><code>int eof(gp_file *)</code> -<dd>Returns 1 if we are at the end of the file, 0 otherwise. Behaves like -<code>feof(FILE *)</code>. - -<dt><code>gp_file * dup(gp_file *, const char *mode)</code> -<dd>Optional function, only used if clist files are to be stored in this filing system. -Behaves like <code>fdup(FILE *)</code>. Leave NULL if not implemented. - -<dt><code>int seekable(gp_file *)</code> -<dd>Returns 1 if the file is seekable, 0 otherwise. Certain output devices will -only work with seekable files. - -<dt><code>int pread(gp_file *, size_t count, gs_offset_t offset, void *buf)</code> -<dd>Optional function, only used if clist files are to be stored in this filing system. -Behaves like an atomic <code>fseek(FILE *, offset, 0)</code> and <code>fread(FILE *, 1, count, buf)</code>. -Akin to <code>pread</code>. - -<dt><code>int pwrite(gp_file *, size_t count, gs_offset_t offset, const void *buf)</code> -<dd>Optional function, only used if clist files are to be stored in this filing system. -Behaves like an atomic <code>fseek(FILE *, offset, 0)</code> and <code>fwrite(FILE *, 1, count, buf)</code>. -Akin to <code>pwrite</code>. - -<dt><code>int is_char_buffered(gp_file *file)</code> -<dd>Returns 1 if the file is character buffered, 0 otherwise. Used for handling -reading from terminals. Very unlikely to be used, so returning 0 all the time -should be safe. Leave NULL to indicate "always 0". - -<dt><code>void fflush(gp_file *file)</code> -<dd>Ensures that any buffered data is written to the file. Behaves like <code>fflush(FILE *)</code>. -Leave NULL to indicate that no flushing is ever required. - -<dt><code>int ferror(gp_file *file)</code> -<dd>Returns non-zero if there has been an error, or 0 otherwise. Behaves like <code>ferror(FILE *)</code>. - -<dt><code>FILE * get_file(gp_file *file)</code> -<dd>Optional: Gets the FILE * pointer that backs this file. Required for a few devices -that insist on working with FILE *'s direct. Generally safe to leave this set to NULL, and those -devices will fail gracefully. - -<dt><code>void clearerr(gp_file *file)</code> -<dd>Clear the error and EOF values for a file. Behaves like <code>clearerror(FILE *)</code>. - -<dt><code>gp_file * reopen(gp_file *f, const char *fname, const char *mode)</code> -<dd>Optional function, only used if the <code>gp_file</code> came from an <code>open_scratch</code> -call; can be left as NULL if the <code>open_scratch</code> pointer is set to NULL. -Reopen a stream with a different mode. Behaves like -<code>freopen(fname, mode, FILE *)</code>. -</dl> - -<h3><a name="callout"></a>Callouts</h3> -<blockquote> -<p>Callouts are a mechanism -for the core code (specifically devices) to communicate with the -user of gsapi. This communication can take the form of passing -information out vis-a-vis what devices are doing, or requesting -configuration from the caller to affect exactly how the device -itself works.</p> -<p>This is deliberately an extensible system, so exact details of -callouts should be documented with the device in question. In general -however a callout handler will be of the form:</p> -<pre> -typedef int (*gs_callout)(void *callout_handle, - const char *device_name, - int id, - int size, - void *data); -</pre> -<p>The <code>callout_handle</code> value passed to the callout will -be the value passed in at registration. The <code>device_name</code> -should be a null-terminated string giving the name of the device -(though care should be taken to cope with the case where -<code>device_name</code> is NULL for potential future uses). -The <code>id</code> value will have a (device-specific) meaning; see -the documentation for the device in question for more details. The -same <code>id</code> value may be used to mean different things in -different devices. -Finally, <code>size</code> and <code>data</code> have callout -specific meanings, but typically, <code>data</code> will be a pointer -to data block (which may either be uninitialised or wholly/partially -initialised on entry, and may be updated on exit), and <code>size</code> -will be the size (in bytes) of the block pointed to by <code>data</code>. -</p> -<p>A return value of -1 (<code>gs_error_unknownerror</code>) means -the callout was not recognised by the handler, and should be passed -to more handlers. Other negative values are interpreted as standard -Ghostscript error values, and stop the propagation of the callout. -Non-negative return codes mean the callout was handled and should -not be passed to any more registered callout handlers.</p> -</blockquote> - -<hr> -<h2><a name="Example_usage"></a>Example Usage</h2> -<p>To try out the following examples in a development environment like Microsoft's -developer tools or Metrowerks Codewarrior, create a new project, save the example -source code as a <tt>.c</tt> file and add it, along with the Ghostscript dll or shared -library. You will also need to make sure the Ghostscript headers are available, either -by adding their location (the <tt>src</tt> directory in the Ghostscript source -distribution) to the project's search path, or by copying ierrors.h and iapi.h into the -same directory as the example source.</p> - -<h3><a name="Example_1"></a>Example 1</h3> -<pre> -/* Example of using GS DLL as a ps2pdf converter. */ - -#if defined(_WIN32) && !defined(_Windows) -# define _Windows -#endif -#ifdef _Windows -/* add this source to a project with gsdll32.dll, or compile it directly with: - * cl -D_Windows -Isrc -Febin\ps2pdf.exe ps2pdf.c bin\gsdll32.lib - */ -# include <windows.h> -# define GSDLLEXPORT __declspec(dllimport) -#endif - -#include "ierrors.h" -#include "iapi.h" - -void *minst = NULL; - -int main(int argc, char *argv[]) -{ - int code, code1; - const char * gsargv[7]; - int gsargc; - gsargv[0] = ""; - gsargv[1] = "-dNOPAUSE"; - gsargv[2] = "-dBATCH"; - gsargv[3] = "-dSAFER"; - gsargv[4] = "-sDEVICE=pdfwrite"; - gsargv[5] = "-sOutputFile=out.pdf"; - gsargv[6] = "input.ps"; - gsargc=7; - - code = gsapi_new_instance(&minst, NULL); - if (code < 0) - return 1; - code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); - if (code == 0) - code = gsapi_init_with_args(minst, gsargc, gsargv); - code1 = gsapi_exit(minst); - if ((code == 0) || (code == gs_error_Quit)) - code = code1; - - gsapi_delete_instance(minst); - - if ((code == 0) || (code == gs_error_Quit)) - return 0; - return 1; -} -</pre> - -<h3>Example 2</h3> -<pre> -/* Similar to command line gs */ - -#if defined(_WIN32) && !defined(_Windows) -# define _Windows -#endif -#ifdef _Windows -/* Compile directly with: - * cl -D_Windows -Isrc -Febin\gstest.exe gstest.c bin\gsdll32.lib - */ -# include <windows.h> -# define GSDLLEXPORT __declspec(dllimport) -#endif -#include <stdio.h> -#include "ierrors.h" -#include "iapi.h" - -/* stdio functions */ -static int GSDLLCALL -gsdll_stdin(void *instance, char *buf, int len) -{ - int ch; - int count = 0; - while (count < len) { - ch = fgetc(stdin); - if (ch == EOF) - return 0; - *buf++ = ch; - count++; - if (ch == '\n') - break; - } - return count; -} - -static int GSDLLCALL -gsdll_stdout(void *instance, const char *str, int len) -{ - fwrite(str, 1, len, stdout); - fflush(stdout); - return len; -} - -static int GSDLLCALL -gsdll_stderr(void *instance, const char *str, int len) -{ - fwrite(str, 1, len, stderr); - fflush(stderr); - return len; -} - -void *minst = NULL; -const char start_string[] = "systemdict /start get exec\n"; - -int main(int argc, char *argv[]) -{ - int code, code1; - int exit_code; - - code = gsapi_new_instance(&minst, NULL); - if (code < 0) - return 1; - gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr); - code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); - if (code == 0) - code = gsapi_init_with_args(minst, argc, argv); - if (code == 0) - code = gsapi_run_string(minst, start_string, 0, &exit_code); - code1 = gsapi_exit(minst); - if ((code == 0) || (code == gs_error_Quit)) - code = code1; - - gsapi_delete_instance(minst); - - if ((code == 0) || (code == gs_error_Quit)) - return 0; - return 1; -} -</pre> - -<h3>Example 3</h3> - -<p>Replace main() in either of the above with the following code, -showing how you can feed Ghostscript piecemeal:</p> -<pre> -const char *command = "1 2 add == flush\n"; - -int main(int argc, char *argv[]) -{ - int code, code1; - int exit_code; - - code = gsapi_new_instance(&minst, NULL); - if (code < 0) - return 1; - code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); - if (code == 0) - code = gsapi_init_with_args(minst, argc, argv); - - if (code == 0) { - gsapi_run_string_begin(minst, 0, &exit_code); - gsapi_run_string_continue(minst, command, strlen(command), 0, &exit_code); - gsapi_run_string_continue(minst, "qu", 2, 0, &exit_code); - gsapi_run_string_continue(minst, "it", 2, 0, &exit_code); - gsapi_run_string_end(minst, 0, &exit_code); - } - - code1 = gsapi_exit(minst); - if ((code == 0) || (code == gs_error_Quit)) - code = code1; - - gsapi_delete_instance(minst); - - if ((code == 0) || (code == gs_error_Quit)) - return 0; - return 1; -} -</pre> - -<h3>Example 4</h3> - -<p>When feeding Ghostscript piecemeal buffers, one can use the normal -operators to configure things and invoke library routines. For example, -to parse a PDF file one could say:</p> - -<pre> - code = gsapi_run_string(minst, "(example.pdf) .runlibfile", 0, &exit_code); -</pre> - -<p>and Ghostscript would open and process the file named "example.pdf" as -if it had been passed as an argument to -<code>gsapi_init_with_args()</code>.</p> -<hr> -<h2><a name="Multiple_threads"></a>Multiple threads</h2> -<p>The Ghostscript library should have been compiled with a -thread safe run time library. -Synchronisation of threads is entirely up to the caller. -The exported <a href="#Exported_functions "><code>gsapi_*()</code></a> -functions must be called from one thread only.</p> -<hr> -<h2><a name="stdio"></a>Standard input and output</h2> -<p> -When using the Ghostscript interpreter library interface, you have a -choice of two standard input/output methods.</p> -<ul> -<li>If you do nothing, the "C" stdio will be used.</li> -<li>If you use <code>gsapi_set_stdio()</code>, all stdio will - be redirected to the callback functions you provide. - This would be used in a graphical user interface environment - where stdio is not available, or where you wish to process - Ghostscript input or output.</li> -</ul> -<p> -The callback functions are described in -<a href="../psi/iapi.h"><code>iapi.h</code></a>.</p> - -<hr> -<h2><a name="display"></a>Display device</h2> -<p> -The <code>display</code> device is available for use with -the Ghostscript interpreter library. While originally designed -for allowing screen display of rendered output from Ghostscript, -this is now powerful enough to provide a simple mechanism for -getting rendered output suitable for use in all manner of -output scenarios, including printing.</p> -<p>Details of the API and options are given in the file -<code><a href="../devices/gdevdsp.h">gdevdsp.h</a></code>. -This device provides you with access to the raster output of -Ghostscript. It is the callers responsibility to copy this raster -to a display window or printer.</p> -<p> -In order for this device to operate, it needs access to a structure -containing a set of callback functions, and a callback handle (an -opaque <code>void *</code> that can be used by caller to locate its -own state). There are 2 ways that the device can get this -information, a legacy method, and a modern method. -</p> -<dl> -<dt>Legacy method</dt> -<dd> -<p>The address of the callback structure, is provided -using <code>gsapi_set_display_callback()</code>. -This must be called after -<code>gsapi_new_instance()</code> -and before -<code>gsapi_init_with_args()</code>.</p> -<p> -With this call, the callback handle is passed as NULL by default, but can -be overridden by using a parameter. We actively dislike -this way of working, as we consider passing addresses -via the command line distasteful. The handle can be -set using</p> -<blockquote> - -sDisplayHandle=1234 -</blockquote> -<p> -Where "1234" is a string. The API was changed to use a string -rather than an integer/long value when support for 64 bit systems -arrived. A display "handle" is often a pointer, and since these -command line options have to survive being processed by Postscript -machinery, and Postscript only permits 32 bit number values, a -different representation was required. Hence changing the value -to a string, so that 64 bit values can be supported. The string -formats allowed are:</p> -<blockquote> -<code>1234</code> - implicit base 10 -</blockquote> -<blockquote> -<code>10#1234</code> - explicit base 10 -</blockquote> -<blockquote> -<code>16#04d2</code> - explicit base 16 -</blockquote> -<p> -The "number string" is parsed by the display device to retrieve -the number value, and is then assigned to the void pointer -parameter "pHandle" in the display device structure. Thus, for -a trivial example, passing <code>-sDisplayHandle=0</code> will result -in the first parameter passed to your display device callbacks being: -<code>(void *)0</code>.</p> -<p> -The previous API, using a number value:</p> -<blockquote> - -dDisplayHandle=1234 -</blockquote> -<p> -is still supported on 32 bit systems, but will cause a "typecheck" -error on 64 bit systems, and is considered deprecated. It should -not be used in new code.</p> -</dd> -<dt>Modern method -<dd> -<p>The preferred method is to register a callout handler using -<code><a href="#register_callout">gsapi_register_callout</a></code>. -When this handler is called for the <code>"display"</code> -device, with <code>id = 0</code> (= <code>DISPLAY_CALLOUT_GET_CALLBACK</code>), -then <code>data</code> should point to an empty <code>gs_display_get_callback_t</code> -block, with <code>size = sizeof(gs_display_get_callback_t)</code>. -</p> -<pre> -typedef struct { - display_callback *callback; - void *caller_handle; -} gs_display_get_callback_t; -</pre> -<p>The handler should fill in the structure before returning, -with a return code of 0.</p> -</dd> -</dl> -<p> -Note, that the <code>DisplayHandle</code> value is only consulted for -display device callbacks registered using the (legacy, now deprecated) -<code>gsapi_set_display_callback</code> API, not the preferred -<code>gsapi_register_callout</code> based mechanism. - -<p> -The device raster format can be configured using</p> -<blockquote> - -dDisplayFormat=NNNN -</blockquote> -<p>Options include</p> -<ul> -<li> native, gray, RGB, CMYK or separation color spaces.</li> -<li> alpha byte (ignored).</li> -<li> 1 to 16 bits/component.</li> -<li> bigendian (RGB) or littleendian (BGR) order.</li> -<li> top first or bottom first raster.</li> -<li> 16 bits/pixel with 555 or 565 bitfields.</li> -<li> Chunky, Planar and Planar interleaved formats.</li> -<li> "Full screen" or "Rectangle Request" modes of operation.</li> -</ul> -<p>The operation of the device is best described with a walkthrough -of some example code that uses it. For simplicity and clarity, we -have omitted the error handling code in this example; in production -code, every place where we get a <code>code</code> value returned -we should check it for failure (a negative value) and clean up -accordingly. First, we create an instance of Ghostscript:</p> -<pre> - void *minst = NULL; - code = gsapi_new_instance(&minst, NULL); - code = gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr); -</pre> -<p>Next, we have to give the display device the address of our -callback structure. In old code, we would do so using something -like this:</p> -<pre> - code = gsapi_set_display_callback(minst, &display_callback); -</pre> -<p>We strongly recommend that you don't do that, but instead use the -more modern <a href="callout">callout</a> mechanism:</p> -<pre> - code = gsapi_register_callout(minst, my_callout_handler, state); -</pre> -<p>where <code>state</code> is any <code>void *</code> value you like, -usually a pointer to help you reach any internal state you may need. -Earlier in your code you would have the definition of -<code>my_callout_handler</code> that might look like this:</p> -<pre> - static int - my_callout_handler(void *instance, - void *callout_handle, - const char *device_name, - int id, - int size, - void *data) -{ - /* On entry, callout_handle == the value of state passed in - * to gsapi_register_callout. */ - /* We are only interested in callouts from the display device. */ - if (device_name == NULL || strcmp(device_name, "display")) - return -1; - - if (id == DISPLAY_CALLOUT_GET_CALLBACK) - { - /* Fill in the supplied block with the details of our callback - * handler, and the handle to use. In this instance, the handle - * is the pointer to our test structure. */ - gs_display_get_callback_t *cb = (gs_display_get_callback_t *)data; - cb->callback = &display_callback; - cb->caller_handle = callout_handle; - return 0; - } - return -1; -} -</pre> -<p>As you can see, this callout handler only responds to callouts -for the display device, and then only for one particular function -(<code>id</code>). It returns the same <code>display_callback</code> -structure as the deprecated, legacy mechanism passed in using -<code>gsapi_set_display_callback</code>, with the added benefit that -the <code>caller_handle</code> value can be passed in too. In this -example we pass in the same value as was used for <code>callout_handle</code>, -but implementations are free to use any value they want.</p> -<p>Returning to our example, we now set up a set of arguments to -setup Ghostscript:</p> -<pre> - int argc = 0; - /* Allow for up to 32 args of up to 64 chars each. */ - char argv[32][64]; - sprintf(argc[argc++], "gs"); - sprintf(argv[argc++], "-sDEVICE=display"); -</pre> -<p>The zeroth arg is a dummy argument to match the standard C mechanism -for passing arguments to a program. Traditionally this is the name of -the program being invoked. Next, we tell Ghostscript to use the display -device.</p> -<pre> - sprintf(argv[argc++], "-sDEVICE=display"); -</pre> -Next we tell the display device what output format to use. The -format is flexible enough to support common Windows, OS/2, Linux -and Mac raster formats. <p>The format values are described in -<code><a href="../devices/gdevdsp.h">gdevdsp.h</a></code>. -To select the display device with a Windows 24-bit RGB raster:</p> -<pre> - sprintf(argv[argc++], "-dDisplayFormat=%d", - DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | - DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST); -</pre> -<p>If (and only if) you used the legacy mechanism described above, you -will need another argument to pass in the <code>caller_handle</code> -value to be parroted back to the functions listed within -<code>display_callback</code>:</p> -<pre> - sprintf(arg2, "-dDisplayHandle=%d", callout_handle); -</pre> -<p>Any other arguments that you want can be added to the end of -the command line, typically including a file to run. Then we pass -that all to Ghostscript: -<pre> - code = gsapi_init_with_args(minst, argc, argv); -</pre> - -<p><a name="display_callback"></a>At this point you should start to -see your display callback functions being called. Exactly which callback -functions are provided, and how they respond will determine exactly -how the display device operates. The primary choice will be whether the -device runs in "full page" or "rectangle request" - mode. Details of these are given below.</p> - -<p>Once we have finished processing the file, we can process -other files using <code>gsapi_run_file</code>, or feed in data -using <code>gsapi_run_string</code>. Once you have finished, you -can shut the interpreter down and exit, using:</p> - -<pre> - code = gsapi_exit(minst); - gsapi_delete_instance(minst); -</pre> - -<p>A full list of the display callback functions can be found in -<code><a href="../devices/gdevdsp.h">gdevdsp.h</a></code>. There -are several different versions of the callback, corresponding to -different "generations" of the device. In general -you should use the latest one. The <code>size</code> field of -the structure should be initialised to the size of the structure -in bytes.</p> - -<h3><a name="display_open"></a>display_open</h3> - -<pre>int (*display_open)(void *handle, void *device);</pre> - -<p>This function will be called when the display device is -opened. The device may be opened and closed many times, -sometimes without any output being produced.</p> - -<h3><a name="display_preclose"></a>display_preclose</h3> - -<pre>int (*display_preclose)(void *handle, void *device);</pre> - -<p>This function will be called when the display device is -about to be closed. The device will not actually be closed -until this function returns.</p> - -<h3><a name="display_close"></a>display_close</h3> - -<pre>int (*display_close)(void *handle, void *device);</pre> - -<p>This function will be called once the display device has -been closed. There will be no more events from the device -unless/until it is reopened.</p> - -<h3><a name="display_presize"></a>display_presize</h3> - -<pre>int (*display_presize)(void *handle, void *device, - int width, int height, int raster, unsigned int format);</pre> - -<p>This function will be called when the display device is -about to be resized. The device will only be resized if this -function returns 0.</p> - -<h3><a name="display_size"></a>display_size</h3> - -<pre>int (*display_size)(void *handle, void *device, int width, int height, - int raster, unsigned int format, unsigned char *pimage);</pre> - -<p>This function will be called when the display device is -has been resized. The pointer to the raster image is pimage.</p> - -<h3><a name="display_sync"></a>display_sync</h3> - -<pre>int (*display_sync)(void *handle, void *device);</pre> - -<p>This function may be called periodically during display -to flush the page to the display.</p> - -<h3><a name="display_page"></a>display_page</h3> - -<pre>int (*display_page)(void *handle, void *device, int copies, int flush);</pre> - -<p>This function is called on a "showpage" operation -(i.e. at the end of every page). Operation will continue as soon as -this function returns.</p> - -<h3><a name="display_update"></a>display_update</h3> - -<pre>int (*display_update)(void *handle, void *device, - int x, int y, int w, int h);</pre> - -<p>This function <strong>may</strong> get called repeatedly -during rendering to indicate that an area of the output has -been updated. Certain types of rendering will not see this -function called back at all (in particular files using -transparency).</p> - -<h3><a name="display_memalloc"></a>display_memalloc</h3> - -<pre>int (*display_memalloc)(void *handle, void *device, - size_t long size);</pre> - -<p><strong>Note:</strong> In older versions of this API, -size is an <code>unsigned long</code> rather than a -<code>size_t</code>.</p> -<p>If this function pointer is sent as NULL, then the -display device will handle all the memory allocations -internally, and will always work in full page rendering -mode.</p> -<p>Otherwise, this function will be called to allocate -the storage for the page to be rendered into. If a non-NULL -value is returned, then the device will proceed to render -the full page into it. If NULL is returned, then the device -will check a) whether we are using a V2 or greater display -callback structure and b) whether that structure specifies -a <code>rectangle_request</code> function pointer.</p> -<p>If both of those conditions are true, then the device -will continue in rectangle request mode. Otherwise it will -fail with an out of memory error.</p> - - -<h3><a name="display_memfree"></a>display_memfree</h3> - -<pre>int (*display_memfree)(void *handle, void *device, void *ptr);</pre> - -<p>This function should be NULL if and only if -<code><a href="#display_memalloc">display_memalloc</a></code> is -NULL. Any memory allocated using <code>display_memalloc</code> will be -freed via this function.</p> - -<h3><a name="display_separation"></a>display_separation</h3> -<pre>int (*display_separation)(void *handle, void *device, - int component, const char *component_name, - unsigned short c, unsigned short m, - unsigned short y, unsigned short k);</pre> - -<p>When using <code>DISPLAY_COLORS_SEPARATION</code>, this function - will be called once for every separation component - first - "Cyan", "Magenta", "Yellow" and - "Black", then any spot colors used. The supplied - <code>c</code>, <code>m</code>, <code>y</code> and <code>k</code> - values give the equivalent color for each spot. Each colorant - value ranges from 0 (for none) to 65535 (full).</p> -<p>In separation color mode you are expected to count the number -of calls you get to this function after each -<code><a href="#display_size">display_size</a></code> to know how many -colors you are dealing with.</p> - -<h3><a name="display_adjust_band_height"></a>display_adjust_band_height</h3> -<pre>int (*display_adjust_band_height)(void *handle, void *device, - int bandheight);</pre> - -<p>When running in "rectangle request mode" the device -first renders the page to a display list internally. It can then -be played back repeatedly so that different regions (rectangles) -of the page can be extracted in sequence. A common use of this is -to support "banded" operation, where the page is divided -into multiple non-overlapping bands of a fixed height.</p> -<p>The display device itself will pick an appropriate band height -for it to use. If this function pointer is left as NULL then this -value will be used unchanged. Otherwise, the proposed value will -be offered to this function. This function can override the choice -of bandheight, by returning the value that it would like to be -used in preference.</p> -<p>In general, this figure should (as much as possible) only be -adjusted downwards. For example, a device targeting an inkjet printer -with 200 nozzles in the print head might like to extract bands -that are a multiple of 200 lines high. So the function might -return <code>max(200, 200*(bandheight/200))</code>. If the function -returns 0, then the existing value will be used unchanged.</p> -<p>Any size rectangle can be chosen with any size bandheight, -so ultimately the value chosen here will not matter much. It -may make some small difference in speed in some cases.</p> - -<h3><a name="display_rectangle_request"></a>display_rectangle_request</h3> -<pre>int (*display_rectangle_request)(void *handle, void *device, - void **memory, int *ox, int *oy, - int *raster, int *plane_raster, - int *x, int *y, int *w, int *h);</pre> - -<p>If the display device chooses to use rectangle request mode, -this function will be called repeatedly to request a rectangle -to render. Ghostscript will render the rectangle, and call this -function again. The implementer is expected to handle the rectangle -that has just been rendered, and to return the details of another -rectangle to render. This will continue until a rectangle with -zero height or width is returned, whereupon Ghostscript will -continue operation.</p> -<p>On entry, <code>*raster</code> and <code>*plane_raster</code> -are set to the values expected by the format in use. All the -other pointers point to uninitialised values.</p> -<p>On exit, the values should be updated appropriately. The -implementor is expected to store the values returned so that -the rendered output given can be correctly interpreted when - control returns to this function.</p> -<p><code>memory</code> should be updated to point to a block of -memory to use for the rendered output. Pixel (<code>*ox</code>, -<code>*oy</code>) is the first pixel represented in that block. -<code>*raster</code> is the number of bytes difference between -the address of component 0 of Pixel(<code>*ox</code>, <code>*oy</code>) -and the address of component 0 of Pixel(<code>*ox</code>, -<code>1+*oy</code>). <code>*plane_raster</code> is the number of -bytes difference between the address of component 0 of -Pixel(<code>*ox</code>, <code>*oy</code>) and the address of -component 1 of Pixel(<code>*ox</code>, <code>*oy</code>), if in -planar mode, 0 otherwise. <code>*x</code>, <code>*y</code>, -<code>*w</code> and <code>*h</code> give the rectangle requested -within that memory block.</p> -<p>Any set of rectangles can be rendered with this method, so this -can be used to drive Ghostscript in various ways. Firstly, it is -simple to request a set of non-overlapping "bands" that -cover the page, to drive a printer. Alternatively, rectangles can -be chosen to fill a given block of memory to implement a window -panning around a larger page. Either the whole image could be -redrawn each time, or smaller rectangles around the edge of the -panned area could be requested. The choice is down to the caller.</p> - -<p> -Some examples of driving this code in full page mode are in -<code><a href="../psi/dwmain.c">dwmain.c</a></code> (Windows), -<code><a href="../psi/dpmain.c">dpmain.c</a></code> (OS/2) and -<code><a href="../psi/dxmain.c">dxmain.c</a></code> (X11/Linux), and -<code><a href="../psi/dmmain.c">dmmain.c</a></code> (MacOS Classic or Carbon).</p> -<p>Alternatively an example that drives this code in both full page -and rectangle request mode can be found in -<code><a href="../demos/c/api_test.c">api_test.c</a></code>.</p> - -<p> -On some platforms, the calling convention for the display device callbacks in -<code><a href="../devices/gdevdsp.h">gdevdsp.h</a></code> -is not the same as the exported -<a href="#Exported_functions "><code>gsapi_*()</code></a> -functions in <a href="../psi/iapi.h"><code>iapi.h</code></a>.</p></p> - -<!-- [2.0 end contents] ==================================================== --> -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small></p> - -<p> -This software is provided AS-IS with no warranty, either express or -implied.</p> - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.</p> - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/C-style.htm b/doc/C-style.htm deleted file mode 100644 index 60443821..00000000 --- a/doc/C-style.htm +++ /dev/null @@ -1,1604 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript C Coding Guidelines</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - - <article> - - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>C Style</h1> - -<h2><a name="toc"></a>Table of contents</h2> - -<ul class="toc"> - <li><a href="#Introduction">Introduction</a></li> - <li><a href="#C_language">C language do's and don'ts</a></li> - <li> - <ul> - <li>Preprocessor: - <a href="#Conditionals">Conditionals</a>, - <a href="#Macros">Macros</a>, - <a href="#Preprocessor_other">Other</a></li> - <li><a href="#Lexical_elements">Lexical elements</a></li> - <li><a href="#Scoping">Scoping</a></li> - <li>Data types: - <a href="#Scalars">Scalars</a>, - <a href="#Arrays">Arrays</a>, - <a href="#Typedefs">Typedefs</a>, - <a href="#Structures">Structures</a>, - <a href="#Unions">Unions</a></li> - <li><a href="#Expressions">Expressions</a></li> - <li><a href="#Statements">Statements</a></li> - <li><a href="#Procedures">Procedures</a> (prototypes and definitions)</li> - <li><a href="#Standard_library">Standard library</a></li> - </ul> - </li> - <li><a href="#Language_extensions">Language extensions</a></li> - <li><a href="#Stylistic_conventions">Stylistic conventions</a></li> - <li> - <ul> - <li>Formatting: - <a href="#Indentation">Indentation</a>, - <a href="#Spaces">Spaces</a>, - <a href="#Parentheses">Parentheses</a></li> - <li><a href="#Preprocessor_style">Preprocessor</a></li> - <li><a href="#Naming">Naming</a></li> - <li><a href="#Types">Types</a></li> - <li><a href="#Procedures_style">Procedures</a>,</li> - <li>Miscellany: - <a href="#Local_variables">Local variables</a>, - <a href="#Compiler_warnings">Compiler warnings</a></li> - </ul> - </li> - <li><a href="#File_structuring">File structuring and naming</a></li> - <li> - <ul> - <li><a href="#All_files">All files</a></li> - <li><a href="#Makefiles">Makefiles</a></li> - <li><a href="#General_C_code">General C Code</a></li> - <li><a href="#Headers">Headers (<code>.h</code> files)</a></li> - <li><a href="#Source">Source (<code>.c</code> files)</a></li> - </ul> - </li> - <li><a href="#Conventions">Ghostscript conventions</a></li> - <li> - <ul> - <li><a href="#Specific_names">Specific names</a>: - <a href="#code"><code>code</code></a>, - <a href="#status"><code>status</code></a></li> - <li><a href="#Structure_type_descriptors">Structure type descriptors</a></li> - <li><a href="#Objects">"Objects"</a></li> - <li><a href="#Error_handling">Error handling</a></li> - </ul> - </li> -</ul> - - - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p> -For other information, see the <a href="Readme.htm">Ghostscript -overview</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Introduction"></a>Introduction</h2> - -<p> -This document describes Ghostscript's C coding conventions. It is primarily -<em>prescriptive</em>, documenting what developers should do when writing -new code; the companion developer documentation (<a - href="Develop.htm">Develop.htm</a>) is primarily <em>descriptive</em>, -documenting the way things are.</p> - -<p> -We encourage following the general language usage and stylistic rules for -any code that will be integrated with Ghostscript, even if the code doesn't -use Ghostscript's run-time facilities or have anything to do with -PostScript, PDF, or page description languages. Ghostscript itself follows -some additional conventions; these are documented separately under "<a -href="#Conventions">Ghostscript conventions</a>" below.</p> - -<hr> - -<h2><a name="C_language"></a>C language do's and don'ts</h2> - -<p> -There are several different versions of the C language, and even of the ANSI -C standard. Ghostscript versions through 7.0 were designed to compile on -pre-ANSI compilers as well as on many compilers that implemented the ANSI -standard with varying faithfulness. Ghostscript versions since 7.0 do not -cater for pre-ANSI compilers: they must conform to the ANSI 1989 standard -(ANS X3.159-1989), with certain restrictions and a few conventional -additions.</p> - -<h3>Preprocessor</h3> - -<h4><a name="Conditionals"></a>Conditionals</h4> - -<p>Restrictions:</p> - -<ul> - -<li>Don't assume that <code>#if</code> will treat undefined names as 0. -While the ANSI standard requires this, it may produce a warning.</li> - -<li>In <code>.c</code> files, don't use preprocessor conditionals that -test for individual platforms or compilers. Use them only in header files -named xxx<code>_.h</code>.</li> - -</ul> - -<h4><a name="Macros"></a>Macros</h4> - -<p> -Restrictions:</p> - -<ul> - -<li>Don't redefine a macro, even with the same definition, without using -<code>#undef</code>.</li> - -<li><code>CAPITALIZE</code> macro names unless there is a good reason not -to.</li> - -<li>Even though the legacy code contains some macros which contain -control flow statments, avoid the use of this in new code and do not -create macros which contain hidden control flow, especially 'return'. -The use of control flow in macros complicates debug significantly -requiring tedious expansion of macros to build a module to be debugged -or resorting to disassembly windows to set breakpoints or to trace -flow.</li> - -<li>Don't use a macro call within a macro argument if the call expands to a -token sequence that includes any commas not within parentheses: this -produces different results depending on whether the compiler expands the -inner call before or after the argument is substituted into the macro body. -(The ANSI standard says that calls must be expanded after substitution, but -some compilers do it the other way.)</li> - -<li>Don't use macro names, even inadvertently, in string constants. Some -compilers erroneously try to expand them.</li> - -<li>Don't use macros to define shorthands for casted pointers. For -instance, avoid - -<blockquote><code> -#define fdev ((gx_device_fubar *)dev) -</code></blockquote> - -<p> -and instead use</p> - -<blockquote><code> -gx_device_fubar * const fdev = (gx_device_fubar *)dev; -</code></blockquote> - -<p> -The use of <code>const</code> alerts the reader that this is effectively -a synonym.</p> -</li> - -<li>If a macro generates anything larger than a single expression (that is, -one or more statements), surround it with <code>BEGIN</code> and -<code>END</code>. These work around the fact that simple statements and -compound statements in C can't be substituted for each other syntactically.</li> - -<li>If a macro introduces local variables, only use names that end with an -underscore (<code>_</code>), such as <code>code_</code>. This avoids -clashes both with ordinary variable names (which should never end with an -underscore) and with system-defined names (which may begin with an -underscore).</li> - -</ul> - -<h3><a name="Preprocessor_other"></a>Other</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Only use <code>#pragma</code> in files that are explicitly identified -as being platform-dependent. Many compilers complain if this is used at -all, and some complain if they don't recognize the specific pragma being -requested (both incorrect according to the ANSI standard).</li> - -</ul> - -<h3><a name="Lexical_elements"></a>Lexical elements</h3> - -<p> -Do not use:</p> - -<ul> - -<li>ANSI trigraphs (??x)</li> -<li>Nested comments (/* /* */ */) (not ANSI compliant, but often accepted)</li> -<li>Multi-character character constants ('abc')</li> -<li>Wide-character character or string constants (L'x', L"x")</li> - -</ul> - -<p> -Restrictions:</p> - -<ul> - -<li>Procedure and static variable names must be 31 characters or less.</li> - -<li>Externally visible procedure and variable names must be unique in the -first 23 characters.</li> - -</ul> - -<h3><a name="Scoping"></a>Scoping (extern, static, ...)</h3> - -<p> -Do not use:</p> - -<ul> - -<li><code>register</code></li> - -</ul> - -<p> -Restrictions:</p> - -<ul> - -<li>Do not allow a global variable (constant) to have more than one -non-<code>extern</code> definition, even though some ANSI C compilers -allow this. Every global constant should have exactly one definition, in a -<code>.c</code> file, and preferably just one <code>extern</code> -declaration, in a header file.</li> - -<li><code>static</code> or variables must be -<code>const</code> and initialized: non-<code>const</code> statically -allocated variables are incompatible with reentrancy, and we're in the -process of eliminating all of them.</li> - -<li>Do not use <code>extern</code> in <code>.c</code> files, only in -<code>.h</code> files, unless you have a very good reason for it (e.g., -as in <a href="../psi/iconf.c">iconf.c</a>). There are too many such -<code>extern</code>s in the code now: we are eliminating them over time.</li> - -<li>Do not declare the same name as both <code>static</code> -and non-<code>static</code> within the same -compilation. (Some compilers complain, some do not.) This is especially a -problem for procedures: it is easy to declare a procedure as -<code>static</code> near the beginning of a file and accidentally not -declare it <code>static</code> where it is defined later in the file.</li> - -<li>Even though the ANSI standard allows initialized external declarations -(<code>extern int x = 0</code>), don't use them.</li> - -</ul> - -<h3><a name="Scalars"></a>Scalars</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Avoid using <code>char</code>, except for <code>char *</code> -for a pointer to a string. Don't assume that <code>char</code> is -signed; also don't assume it is unsigned.</li> - -<li>Never cast a <code>float</code> to a <code>double</code> -explicitly. ANSI compilers in their default mode do all floating point -computations in double precision, and handle such casts automatically.</li> - -<li>Don't use <code>long long</code>: even though it is in the ANSI -standard, not all compilers support it. Use the -<code>(u)int64_t</code> types from <code>stdint_.h</code> instead.</li> - -<li>Don't assume anything about whether <code>sizeof(long)</code> is less -than, equal to, or greater than <code>sizeof(ptr)</code>. (However, you -can make such comparisons in preprocessor conditionals using -<code>ARCH_SIZEOF_LONG</code> and <code>ARCH_SIZEOF_PTR</code>.)</li> - -</ul> - -<h3><a name="Arrays"></a>Arrays</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Don't declare arrays of size 0. (The newer ANSI standard allows this, -but the older one doesn't.)</li> - -<li>Don't declare an array of size 1 at the end of a structure to indicate -that a variable-size array follows.</li> - -<li>Don't declare initialized <code>auto</code> arrays.</li> - -</ul> - -<h3><a name="Typedefs"></a>Typedefs</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Don't use <code>typedef</code> for function types, such as: - -<blockquote> -<code>typedef int proc_xyz_t(double, int *);</code> -</blockquote> - -<p>Many compilers don't handle this correctly -- they will give errors, or -do the wrong thing, when declaring variables of type -<code>proc_xyz_t</code> and/or <code>proc_xyz_t *</code>. Instead, do -this:</p> - -<blockquote> -<code>#define PROC_XYZ(proc) int proc(double, int *)<br> -PROC_XYZ(some_proc); /* declare a procedure of this type */<br> -typedef PROC_XYZ((*proc_xyz_ptr_t)); /* define a type for procedure ptrs */<br> -<br> -proc_xyz_ptr_t pp; /* pointer to procedure */</code> -</blockquote> -</li> -<li>Don't redefine <code>typedef</code>'ed names, even with the same -definition. Some compilers complain about this, and the standard doesn't -allow it.</li> - -</ul> - -<h3><a name="Structures"></a>Structures</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Don't use anonymous structures if you can possibly avoid it, except -occasionally as components of other structures. Ideally, use the -<code>struct</code> keyword only for declaring named structure types, -like this: - -<blockquote> -<code>typedef struct xxx_s {</code><br> - ... members ...<br> -<code>} xxx_t;</code> -</blockquote> -</li> -<li>Use <code>struct</code> only when declaring structure types, never -for referring to them (e.g., never declare a variable as type -<code>struct xxx_s *</code>).</li> - -<li>Don't assume that the compiler will (or won't) insert padding in -structures to align members for best performance. To preserve alignment, -only declare structure members that are narrower than an <code>int</code> -if there will be a lot of instances of that structure in memory. For such -structures, insert <code>byte</code> and/or <code>short</code> padding -members as necessary to re-establish <code>int</code> alignment.</li> - -<li>Don't declare initialized <code>auto</code> structures.</li> - -</ul> - -<h3><a name="Unions"></a>Unions</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Use unions only as components of structures, not as typedefs in their -own right.</li> - -<li>Don't attempt to initialize unions: not all compilers support this, even -though it is in the 1989 ANSI standard.</li> - -</ul> - -<h3><a name="Expressions"></a>Expressions</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Don't assign a larger integer data type to a smaller one without a cast -(<code>int_x = long_y</code>).</li> - -<li>It's OK to use the address of a structure or array element -(<code>&p->e</code>, <code>&a[i]</code>) locally, or pass it to a -procedure that won't store it, but don't store such an address in allocated -storage unless you're very sure of what you're doing.</li> - -<li>Don't use conditional expressions with structure or union values. -(Pointers to structures or unions are OK.)</li> - -<li>For calling a variable or parameter procedure, use -<code>ptr->func(...)</code>. Some old code uses explicit indirection, -<code>(*ptr->func)(...)</code>: don't use this in new code.</li> - -<li>Don't write expressions that depend on order of evaluation, unless the -order is created explicitly by use of <code>||</code>, -<code>&&</code>, <code>?:</code>, <code>,</code>, or -function nesting (the arguments of a function must be evaluated before the -function is called). In particular, don't assume that the arguments of a -function will be evaluated left-to-right, or that the left side of an -assignment will be evaluated before the right.</li> - -<li>Don't mix integer and enumerated types ad lib: treat enumerated types as -distinct from integer types, and use casts to convert between the two. -(Some compilers generate warnings if you do not do this.)</li> - -</ul> - -<h3><a name="Statements"></a>Statements</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>If you use an expression as a statement, other than an assignment or a -function call with <code>void</code> return value, enclose it explicitly -in <code>DISCARD()</code>.</li> - -<li>The type of the operand of a <code>switch</code> must match the type -of the case labels, whether the labels are <code>int</code>s or the -members of an <code>enum</code> type. (Use a cast if necessary.)</li> - -<li>It is OK for one case of a switch to "fall through" into another (i.e., -for the statement just before a case label not to be a control transfer), -but a comment <code>/* falls through */</code> is -required.</li> - -<li>If you are returning an error code specified explicitly (e.g., -<code>return gs_error_rangecheck</code>), use -<code>return_error()</code> rather than plain <code>return</code>. -However, if the program is simply propagating an error code generated -elsewhere, as opposed to generating the error, use <code>return</code> -(e.g., <code>if (code < 0) return code</code>).</li> - -</ul> - -<h3><a name="Procedures"></a>Procedures</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Provide a prototype for every procedure, and make sure the prototype is -available at every call site. If the procedure is local to a file -(<code>static</code>), the prototype should precede the procedure, in -the same file; if the procedure is global, the prototype should be in a -header file.</li> - -<li>If a procedure parameter is itself a procedure, do list its parameter -types rather than just using <code>()</code>. For example: - -<blockquote><code> -int foo(int (*callback)(int, int)); -</code></blockquote> - -<p> -rather than just</p> - -<blockquote><code> -int foo(int (*callback)()); -</code></blockquote> -</li> -<li>Don't use the <code>P</code>* macros in new code. (See the -Procedures section of <a href="#Language_extensions">Language extensions</a> -below for more information.)</li> - -<li>Always provide an explicit return type for procedures, in both the -prototype and the definition: don't rely on the implicit declaration as -<code>int</code>.</li> - -<li>Don't use <code>float</code> as the return type of a procedure, -unless there's a special reason. Floating point hardware typically does -everything in double precision internally and has to do extra work to -convert between double and single precision.</li> - -<li>Don't declare parameters as being of type <code>float</code>, -<code>short</code>, or <code>char</code>. If you do this and forget -to include the prototype at a call site, ANSI compilers will generate -incompatible calling sequences. Use <code>double</code> instead of -<code>float</code>, and use <code>int</code> or <code>uint</code> -instead of <code>short</code> or <code>char</code>.</li> - -</ul> - -<h3><a name="Standard_library"></a>Standard library</h3> - -<p> -Restrictions:</p> - -<ul> - -<li>Only use library features that are documented in the established ANSI -standard (e.g., Harbison & Steele's book). Do not use procedures that are -"standards" promulgated by Microsoft (e.g., <code>stricmp</code>), or -originate in BSD Unix (e.g., <code>strcasecmp</code>), or were added in -later versions of the standard such as C 9X.</li> - -<li>Do not use any features from <code>stdio.h</code> that assume the -existence of <code>stdin</code>, <code>stdout</code>, or -<code>stderr</code>. See <a href="../base/gsio.h">gsio.h</a> for the full -list. Instead, use <code>gs_stdin</code> et al.</li> - -</ul> - -<hr> - -<h2><a name="Language_extensions"></a>Language extensions</h2> - -<h3>Scoping</h3> - -<dl> - -<dt><code>static</code></dt> - -<dd>Ghostscript assumes the compiler supports the <code>static</code> -keyword for declaring variables and procedures as local to a particular -source file.</dd> - -<dt><code>inline</code></dt> - -<dd><code>inline</code> is available even if the compiler does not -support it. Be aware, however, that it may have no effect. In particular, -do not use <code>inline</code> in header files. Instead, use the -<code>extern_inline</code> facility described just below.</dd> - -<dt><code>extern_inline</code></dt> - -<dd>Compilers that do support <code>inline</code> vary in how they decide -whether to (also) compile a closed-code copy of the procedure. Because of -this, putting an <code>inline</code> procedure in a header file may -produce multiple closed copies, causing duplicate name errors at link time. -<code>extern_inline</code> provides a safe way to put -<code>inline</code> procedures in header files, regardless of compiler. -Unfortunately, the only way we've found to make this fully portable involves -a fair amount of boilerplate. For details, please see <a -href="../base/stdpre.h">stdpre.h</a>.</dd> - -</dl> - -<h3>Scalar types</h3> - -<dl> - -<dt><code>bool, true, false</code></dt> - -<dd><code>bool</code> is intended as a Boolean type, with canonical -values <code>true</code> and <code>false</code>. In a more reasonable -language, such as Java, <code>bool</code> is an enumerated type requiring -an explicit cast to or from <code>int</code>; however, because C's -conditionals are defined as producing <code>int</code> values, we can't -even define <code>bool</code> as a C <code>enum</code> without -provoking compiler warnings. -<p> -Even though <code>bool</code> is a synonym for <code>int</code>, treat -them as conceptually different types:</p> - - -<ul> -<li>Initialize or set <code>bool</code> variables to <code>true</code> -or <code>false</code>, not 0 or 1.</li> -<li>Use the Boolean operators <code>!</code>, <code>&&</code>, -and <code>||</code> only with Booleans. Don't use the idiom -<code>!!x</code> to create a Boolean that is true iff <code>x</code> -!= 0: use <code>x != 0</code>.</li> -<li>Use an explicit <code>(int)</code> cast to convert a Boolean to an -integer.</li> -</ul> -</dd> -<dt><code>byte, ushort, uint, ulong</code></dt> - -<dd>These types are simply shorthands for <code>unsigned char, short, int, -long</code>. - -<p> -In addition, the use of <code>byte *</code> indicates a -Ghostscript-style string, with explicit length given separately, as -opposed to a null terminated C-style string, which is <code>char -*</code>.</p> -</dd> -<dt><code>bits8, bits16, bits32</code></dt> - -<dd>These are unsigned integer types of the given width. Use them wherever -the actual width matters: do <em>not</em>, for example, use -<code>short</code> assuming that it is 16 bits wide. New code can use -the C99 fixed-width types from <code>stdint_.h</code>.</dd> - -</dl> - -<hr> - -<h2><a name="Stylistic_conventions"></a>Stylistic conventions</h2> - -<p> -Ghostscript's coding rules cover not only the use of the language, but also -many stylistic issues like the choice of names and the use of whitespace. -The stylistic rules are meant to produce code that is easy to read. It's -important to observe them as much as possible in order to maintain a -consistent style, but if you find these rules getting in your way or -producing ugly-looking results once in a while, it's OK to break it.</p> - -<h3><a name="Formatting"></a>Formatting</h3> - -<h4><a name="Indentation"></a>Indentation</h4> - -<p> -We've formatted all of our code using the GNU <code>indent</code> program.</p> - -<blockquote><code> -indent -bad -nbap -nsob -br -ce -cli4 -npcs -ncs \<br> - -i4 -di0 -psl -lp -lps -nut somefile.c -</code></blockquote> - -<p> -does a 98% accurate job of producing our preferred style. Unfortunately, -there are bugs in all versions of GNU <code>indent</code>, requiring -both pre- and post-processing of the code.</p> - -<p> -Put indentation points every 4 spaces. Never use tab stops!</p> - -<p> -Don't indent the initial <code>#</code> of preprocessor commands. -However, for nested preprocessor commands, do use indentation between the -<code>#</code> and the command itself. Use 2 spaces per level of -nesting, e.g.:</p> - -<blockquote> -<code>#ifndef xyz</code><br> -<code># define xyz 0</code><br> -<code>#endif</code> -</blockquote> - -<p> -For assignments (including chain assignments), put the entire statement on -one line if it will fit; if not, break it after a <code>=</code> and -indent all the following lines. I.e., format like this:</p> - -<blockquote> -var1 <code>=</code> value<code>;</code><br> -var1 <code>=</code> var2 <code>=</code> value<code>;</code><br> -var1 <code>=</code><br> - value<code>;</code><br> -var1 <code>=</code><br> - var2 <code>=</code> value<code>;</code><br> -var1 <code>=</code> var2 <code>=</code><br> - value<code>;</code> -</blockquote> - -<p> -But not like this:</p> - -<blockquote> -var1 <code>=</code><br> -var2 <code>=</code> value<code>;</code> -</blockquote> - -<p> -Indent in-line blocks thus:</p> - -<blockquote> -<code>{</code><br> - ... declarations ...<br> - {{ blank line if any declarations above }}<br> - ... statements ...<br> -<code>}</code> -</blockquote> - -<p> -Similarly, indent procedures thus:</p> - -<blockquote> -return_type<br> -proc_name(... arguments ...)<br> -<code>{</code><br> - ... declarations ...<br> - {{ blank line if any declarations above }}<br> - ... statements ...<br> -<code>}</code> -</blockquote> - -<p> -If a control construct (<code>if</code>, <code>do</code>, -<code>while</code>, or <code>for</code>) has a one-line body, use -this:</p> - -<blockquote> -... control construct ...<br> - ... subordinate simple statement ... -</blockquote> - -<p>This is considered particularly important so that a breakpoint can be -set inside the conditional easily.</p> - -<p> -If it has a multi-line body, use this:</p> - -<blockquote> -... control construct ... <code>{</code><br> - ... subordinate code ...<br> -<code>}</code> -</blockquote> - -<p> -If the subordinate code has declarations, see blocks above.</p> - -<p> -For if-else statements, do this:</p> - -<blockquote> -<code>if (</code> ...<code> ) {</code><br> - ... subordinate code ...<br> -<code>} else if (</code> ...<code> ) {</code><br> - ... subordinate code ...<br> -<code>} else {</code><br> - ... subordinate code ...<br> -<code>}</code> -</blockquote> - -<p> -When there are more than two alternatives, as in the example above, use the -above ("parallel") syntax rather than the following ("nested") syntax:</p> - -<blockquote> -<code>if (</code> ...<code> ) {</code><br> - ... subordinate code ...<br> -<code>} else {</code><br> -<code> if (</code> ...<code> ) {</code><br> - ... subordinate code ...<br> -<code> } else {</code><br> - ... subordinate code ...<br> -<code> }</code><br> -<code>}</code> -</blockquote> - -<p> -Similarly, for do-while statements, do this:</p> - -<blockquote> -<code>do {</code><br> - ... body ...<br> -<code>} while (</code> ... condition ... <code>);</code> -</blockquote> - -<h4><a name="Spaces"></a>Spaces</h4> - -<p> -Do put a space:</p> -<ul> -<li>after every comma and semicolon, unless it ends a line;</li> -<li>around every binary operator other than "<code>-></code>" and -"<code>.</code>", although you can omit the spaces around the innermost -operator in a nested expression if you like;</li> -<li>on both sides of the parentheses of an <code>if</code>, <code>for</code>, or <code>while</code>.</li> -</ul> - -<p> -Don't put a space:</p> -<ul> -<li>at the end of a line;</li> -<li>before a comma or semicolon;</li> -<li>after unary prefix operators;</li> -<li>before the parenthesis of a macro or procedure call.</li> -</ul> - -<h4><a name="Parentheses"></a>Parentheses</h4> - -<p> -Parentheses are important in only a few places:</p> - -<ul> -<li>Around the inner subexpressions in expressions that mix -<code>&&</code> and <code>||</code>, even if they are not -required by precedence, for example: - -<blockquote><code> -(xx && yy) || zz -</code></blockquote> -</li> -<li>Similarly around inner subexpressions in expressions that mix -<code>&</code>, <code>|</code>, or shifts, especially if mixing -these with other operators, for instance: - -<blockquote><code> -(x << 3) | (y >> 5) -</code></blockquote> -</li> -<li>In macro definitions around every use of an argument that logically -could be an expression, for example: - -<blockquote><code> -((x) * (x) + (y) * (y)) -</code></blockquote> -</li> -</ul> - -<p> -Anywhere else, given the choice, use fewer parentheses.</p> - -<p> -For stylistic consistency with the existing Ghostscript code, put -parentheses around conditional expressions even if they aren't -syntactically required, unless you really dislike doing this. Note that -the parentheses should go around the entire expression, not the condition. -For instance, instead of:</p> - -<blockquote><code> -hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y,<br> - (pgls->g.pen_down) ? gs_lineto : gs_moveto); -</code></blockquote> - -<p> -use:</p> - -<blockquote><code> -hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y,<br> - (pgls->g.pen_down ? gs_lineto : gs_moveto)); -</code></blockquote> - -<h3><a name="Preprocessor_style"></a>Preprocessor</h3> - -<h4>Conditionals</h4> - -<p> -Using preprocessor conditionals can easily lead to unreadable code, since -the eye really wants to read linearly rather than having to parse the -conditionals just to figure out what code is relevant. It's OK to use -conditionals that have small scope and that don't change the structure or -logic of the program (typically, they select between different sets of -values depending on some configuration parameter), but where possible, break -up source modules rather than use conditionals that affect the structure or -logic.</p> - -<h4>Macros</h4> - -<p> -Ghostscript code uses macros heavily to effectively extend the rather -weak abstraction capabilities of the C language, specifically in the area of -memory management and garbage collection: in order to read Ghostscript code -effectively, you simply have to learn some of these macros as though they -were part of the language. The current code also uses macros heavily for -other purposes, but we are trying to phase these out as rapidly as possible, -because they make the code harder to read and debug, and to use the -rules that follow consistently in new code.</p> - -<p> -Define macros in the smallest scope you can manage (procedure, file, or -<code>.h</code> file), and <code>#undef</code> them at the end of -that scope: that way, someone reading the code can see the definitions -easily when reading the uses. If that isn't appropriate, define them in as -large a scope as possible, so that they effectively become part of the -language. This places an additional burden on the reader, but it can be -amortized over reading larger amounts of code.</p> - -<p> -Try hard to use procedures instead of macros. Use "<code>inline</code>" -if you really think the extra speed is needed, but only within a -<code>.c</code> file: don't put inline procedures in <code>.h</code> -files, because most compilers don't honor "<code>inline</code>" and -you'll wind up with a copy of the procedure in every <code>.c</code> -file that includes the <code>.h</code> file.</p> - -<p> -If you define a macro that looks like a procedure, make sure it will work -wherever a procedure will work. In particular, put parentheses around every -use of an argument within the macro body, so that the macro will parse -correctly if some of the arguments are expressions, and put parentheses -around the entire macro body. (This is still subject to the problem that an -argument may be evaluated more than once, but there is no way around this in -C, since C doesn't provide for local variables within expressions.)</p> - -<p> -If you define macros for special loop control structures, make their uses -look somewhat like ordinary loops, for instance:</p> - -<blockquote> -<code>BEGIN_RECT(xx, yy) {</code><br> - ... body indented one position ...<br> -<code>} END_RECT(xx, yy);</code> -</blockquote> - -<p> -If at all possible, don't use free variables in macros -- that is, variables -that aren't apparent as arguments of the macro. If you must use free -variables, list them all in a comment at the point where the macro is -defined.</p> - -<p> -If you define new macros or groups of macros, especially if they aren't -simply inline procedures or named constant values, put some extra effort -into documenting them, to compensate for the fact that macros are -intrinsically harder to understand than procedures.</p> - -<h3><a name="Comments"></a>Comments</h3> - -<p> -The most important descriptive comments are ones in header files that -describe structures, including invariants; but every procedure or structure -declaration, or group of other declarations, should have a comment. Don't -spend a lot of time commenting executable code unless something unusual or -subtle is going on.</p> - -<h3><a name="Naming"></a>Naming</h3> - -<p> -Use fully spelled-out English words in names, rather than contractions. -This is most important for procedure and macro names, global variables and -constants, values of <code>#define</code> and <code>enum</code>, -<code>struct</code> and other <code>typedef</code> names, and -structure member names, and for argument and variable names which have -uninformative types like <code>int</code>. It's not very important for -arguments or local variables of distinctive types, or for local index or -count variables.</p> - -<p> -Avoid names that run English words together: -"<code>hpgl_compute_arc_center</code>" is better than -"<code>hpgl_compute_arccenter</code>". However, for terms drawn from -some predefined source, like the names of PostScript operators, use a term -in its well-known form (for instance, <code>gs_setlinewidth</code> -rather than <code>gs_set_line_width</code>).</p> - -<p> -Procedures, variables, and structures visible outside a single -<code>.c</code> file should generally have prefixes that indicate what -subsystem they belong to (in the case of Ghostscript, <code>gs_</code> -or <code>gx_</code>). This rule isn't followed very consistently.</p> - -<h3><a name="Types"></a>Types</h3> - -<p> -Many older structure names don't have <code>_t</code> on the end, but -this suffix should be used in all new code. (The <code>_s</code> -structure name is needed only to satisfy some debuggers. No code other than -the structure declaration should refer to it.)</p> - -<p> -Declare structure types that contain pointers to other instances of -themselves like this:</p> - -<blockquote> -<code>typedef struct xxx_s xxx_t;</code><br> -<code>struct xxx_s {</code><br> - ... members ...<br> - <code>xxx_t *</code>ptr_member_name;<br> - ... members ...<br> -<code>};</code> -</blockquote> - -<p> -If, to maintain data abstraction and avoid including otherwise unnecessary -header files, you find that you want the type <code>xxx_t</code> to be -available in a header file that doesn't include the definition of the -structure <code>xxx_s</code>, use this approach:</p> - -<blockquote> -<code>#ifndef xxx_DEFINED</code><br> -<code># define xxx_DEFINED</code><br> -<code>typedef struct xxx_s xxx_t;</code><br> -<code>#endif</code><br> -<code>struct xxx_s {</code><br> - ... members ...<br> -<code>};</code> -</blockquote> - -<p> -You can then copy the first 4 lines in other header files. (Don't ever -include them in an executable code file.)</p> - -<p> -Don't bother using <code>const</code> for anything other than with -pointers as described below. However, in those places where it is necessary -to cast a pointer of type <code>const T *</code> to type -<code>T *</code>, always include a comment that explains why you are -"breaking const".</p> - -<h4>Pointers</h4> - -<p> -Use <code>const</code> for pointer referents (that is, -<code>const T *</code>) wherever possible and appropriate.</p> - -<p> -If you find yourself wanting to use <code>void *</code>, try to -find an alternative using unions or (in the case of super- and subclasses) -casts, unless you're writing something like a memory manager that really -treats memory as opaque.</p> - -<h3><a name="Procedures_style"></a>Procedures</h3> - -<p> In general, don't create procedures that are private and only called -from one place. However, if a compound statement (especially an arm of -a conditional) is too long for the eye easily to match its enclosing -braces "<code>{...}</code>" -- that is, longer than 10 or 15 lines -- -and it doesn't use or set a lot of state held in outer local variables, -it may be more readable if you put it in a procedure.</p> - -<h3>Miscellany</h3> - -<h4><a name="Local_variables"></a>Local variables</h4> - -<p> -Don't assign new values to procedure parameters. It makes debugging very -confusing when the parameter values printed for a procedure are not the -ones actually supplied by the caller. Instead use a separate local -variable initialized to the value of the parameter.</p> - -<p> -If a local variable is only assigned a value once, assign it that value at -its declaration, if possible. For example,</p> - -<blockquote> -<code>int x = </code>some expression <code>;</code> -</blockquote> - -<p> -rather than</p> - -<blockquote> -<code>int x;</code><br> -...<br> -<code>x = </code> some expression <code>;</code> -</blockquote> - -<p> -Use a local pointer variable like this to "narrow" pointer types:</p> - -<blockquote> -<code>int</code><br> -someproc(... <code>gx_device *dev</code> ...)<br> -<code>{<br> - gx_device_printer *const pdev = (gx_device_printer *)dev;</code><br> - ...<br> -<code>}</code> -</blockquote> - -<p> -Don't "shadow" a local variable or procedure parameter with an inner local -variable of the same name. I.e., don't do this:</p> - -<blockquote> -<code>int</code><br> -someproc(... <code>int x</code> ...)<br> -<code>{</code><br> - ...<br> -<code> int x;</code><br> - ...<br> -<code>}</code> -</blockquote> - -<h4><a name="Compiler_warnings"></a>Compiler warnings</h4> - -<p> -We want Ghostscript to compile with no warnings. This is a constant -battle as compilers change and new code is added. Work hard to eliminate -warnings by improving the code structure instead of patching over them. -If the compiler can't figure out that a variable is always initialized, -a future reader will probably have trouble as well.</p> - -<hr> - -<h2><a name="File_structuring"></a>File structuring</h2> - -<h3><a name="All_files"></a>All files</h3> - -<p> -Keep file names within the "8.3" format for portability:</p> -<ul> -<li>Use only letters, digits, dash, and underscore in file names.</li> -<li>Don't assume upper and lower case letters are distinct.</li> -<li>Put no more than 8 characters before the ".", if any.</li> -<li>If there is a ".", put between 1 and 3 characters after the ".".</li> -</ul> - -<p> -For files other than documentation files, use only lower case letters -in the names; for HTML documentation files, capitalize the first letter.</p> - -<p> -Every code file should start with comments containing</p> - -<ol> -<li>a copyright notice,</li> -<li>the name of the file in the form of an RCS Id: - -<blockquote><code> -/* $Id: filename.ext $*/ -</code></blockquote> - -<p> -(using the comment convention appropriate to the language of the file), and</p> -</li> -<li>a summary, no more than one line, of what the file contains.</li> -</ol> - -<p> -If you create a file by copying the beginning of another file, be sure to -update the copyright year and change the file name.</p> - -<h3><a name="Makefiles"></a>Makefiles</h3> - -<p> -Use the extension <code>.mak</code> for makefiles.</p> - -<p> -For each</p> - -<blockquote><code> -#include "xxx.h" -</code></blockquote> - -<p> -make sure there is a dependency on <code>$(xxx_h)</code> in the -makefile. If xxx ends with a "<code>_</code>", this rule still holds, -so that if you code</p> - -<blockquote><code> -#include "math_.h" -</code></blockquote> - -<p> -the makefile must contain a dependency on "<code>$(math__h)</code>" -(note the two underscores "<code>__</code>").</p> - -<p> -List the dependencies bottom-to-top, like the <code>#include</code> -statements themselves; within each level, list them alphabetically. Do -this also with <code>#include</code> statements themselves whenever -possible (but sometimes there are inter-header dependencies that require -bending this rule).</p> - -<p> -For compatibility with the build utilities on OpenVMS, always put a space -before the colon that separates the target(s) of a rule from the dependents.</p> - -<h3><a name="General_C_code"></a>General C code</h3> - -<p> -List <code>#include</code> statements from "bottom" to "top", that is, -in the following order:</p> - -<blockquote><ol> -<li>System includes (<code>"xxx_.h"</code>)</li> -<li><code>gs*.h</code></li> -<li><code>gx*.h</code> (yes, <code>gs</code> and <code>gx</code> -are in the wrong order.)</li> -<li><code>s*.h</code></li> -<li><code>i*.h</code> (or other interpreter headers that don't start -with "<code>i</code>")</li> -</ol></blockquote> - -<h3><a name="Headers"></a>Headers (<code>.h</code> files)</h3> - -<p> -In header files, always use the following at the beginning of a header file -to prevent double inclusion:</p> - -<blockquote> -{{ Copyright notice etc. }}<br><br> - -<code>#ifndef </code><filename><code>_INCLUDED</code><br> -<code>#define </code><filename><code>_INCLUDED</code><br><br> - -{{ The contents of the file }}<br><br> - -<code>#endif /* </code><filename><code>_INCLUDED */</code> -</blockquote> - -<p> -The header file is the first place that a reader goes for -information about procedures, structures, constants, etc., so ensure that -every procedure and structure has a comment that says what it does. Divide -procedures into meaningful groups set off by some distinguished form of -comment.</p> - -<h3><a name="Source"></a>Source (<code>.c</code> files)</h3> - -<p> -After the initial comments, arrange C files in the following order:</p> - -<blockquote><ol> -<li><code>#include</code> statements</li> -<li>Exported data declarations</li> -<li>Explicit externs (if necessary)</li> -<li>Forward declarations of procedures</li> -<li>Private data declarations</li> -<li>Exported procedures</li> -<li>Private procedures</li> -</ol></blockquote> - -<p> -Be flexible about the order of the declarations if necessary to improve -readability. Many older files don't follow this order, often without good -reason.</p> - -<hr> - -<h2><a name="Conventions"></a>Ghostscript conventions</h2> - -<h3><a name="Specific_names"></a>Specific names</h3> - -<p> -The Ghostscript code uses certain names consistently for certain kinds of -values. Some of the commonest and least obvious are these two:</p> - -<h4><a name="code"></a><code>code</code></h4> - -<blockquote> -<p>A value to be returned from a procedure:</p> - -<table> -<tr> - <td align="right">< 0</td> - <td colspan="2">An error code defined in <a href="../base/gserrors.h">gserrors.h</a> (or <a href="../psi/ierrors.h">ierrors.h</a>)</td> -</tr> -<tr> - <td align="right">0</td> - <td colspan="2">Normal return</td> -</tr> -<tr> - <td align="right">> 0</td> - <td colspan="2">A non-standard but successful return (which must be documented, preferably with the procedure's prototype)</td> -</tr> -</table> - -</blockquote> - -<h4><a name="status"></a><code>status</code></h4> - -<blockquote> -<p>A value returned from a stream procedure:</p> - -<table> -<tr> - <td align="right">< 0</td> - <td colspan="2">An exceptional condition as defined in <a href="../base/scommon.h">scommon.h</a></td> -</tr> -<tr> - <td align="right">0</td> - <td colspan="2">Normal return (or, from the "<code>process</code>" procedure, means that more input is needed)</td> -</tr> -<tr> - <td align="right">1</td> - <td colspan="2">More output space is needed (from the "<code>process</code>" procedure)</td> -</tr> -</table> -</blockquote> - -<h3><a name="Structure_type_descriptors"></a>Structure type descriptors</h3> - -<p> -The Ghostscript memory manager requires run-time type information for every -structure. (We don't document this in detail here: see the <a -href="Develop.htm#Structure_descriptors">Structure descriptors</a> section -of the developer documentation for details.) Putting the descriptor for a -structure next to the structure definition will help keep the two -consistent, so immediately after the definition of a structure -<code>xxx_s</code>, define its structure descriptor:</p> - -<blockquote> -<code>struct xxx_s {</code><br> - ... members ...<br> -<code>};</code><br> -<code>#define private_st_xxx() /* in </code><filename><code>.c */\</code><br> -<code> gs_private_st_</code><whatever><code>(st_xxx, xxx_t,\</code><br> -<code> "xxx_t", xxx_enum_ptrs, xxx_reloc_ptrs,\</code><br> -<code> </code>... additional parameters as needed ...<code>)</code> -</blockquote> - -<p> -The file that implements operations on this structure -(<filename><code>.c</code>) should then include, near the -beginning, the line:</p> - -<blockquote> -<code>private_st_xxx();</code> -</blockquote> - -<p> -In much existing code, structure descriptors are declared as -<code>public</code>, which allows clients to allocate instances of the -structure directly. We now consider this bad design. Instead, structure -descriptors should always be <code>static</code>; the implementation -file should provide one or more procedures for allocating instances, e.g.,</p> - -<blockquote> -<code>xxx_t *gs_xxx_alloc(P1(gs_memory_t *mem));</code> -</blockquote> - -<p> -If it is necessary to make a structure descriptor public, it should be -declared in its clients as</p> - -<blockquote> -<code>extern_st(st_xxx);</code> -</blockquote> - -<h3><a name="Objects"></a>"Objects"</h3> - -<p> -Ghostscript makes heavy use of object-oriented constructs, including -analogues of classes, instances, subclassing, and class-associated -procedures. However, these constructs are implemented in C rather than C++, -for two reasons:</p> - -<ul> - -<li>The first Ghostscript code was written in 1986, long before C++ was -codified or was well supported by tools. Even today, C++ tools rarely -support C++ as well as C tools support C.</li> - -<li>C++ imposes its own implementations for virtual procedures, inheritance, -run-time type information, and (to some extent) memory management. -Ghostscript requires use of its own memory manager, and also sometimes -requires the ability to change the virtual procedures of an object -dynamically.</li> - -</ul> - -<h4>Classes</h4> - -<p> -The source code representation of a class is simply a -<code>typedef</code> for a C <code>struct</code>. See <a -href="C-style.htm#Structures">Structures</a>, above, for details.</p> - -<h4>Procedures</h4> - -<p> -Ghostscript has no special construct for non-virtual procedures associated -with a class. In some cases, the <code>typedef</code> for the class is -in a header file but the <code>struct</code> declaration is in the -implementation code file: this provides an extra level of opaqueness, since -clients then can't see the representation and must make all accesses through -procedures. You should use this approach in new code, if it doesn't -increase the size of the code too much or require procedure calls for very -heavily used accesses.</p> - -<p> -Ghostscript uses three different approaches for storing and accessing -virtual procedures, plus a fourth one that is recommended but not currently -used. For exposition, we assume the class (type) is named -<code>xxx_t</code>, it has a virtual procedure -<code>void (*virtu)(P1(xxx_t *))</code>, and we have a variable -declared as <code>xxx_t *pxx</code>.</p> - -<ol> - -<li>The procedures are stored in a separate, constant structure of type -<code>xxx_procs</code>, of which <code>virtu</code> is a member. The -structure definition of <code>xxx_t</code> includes a member defined as -<code>const xxx_procs *procs</code> (always named -<code>procs</code>). The construct for calling the virtual procedure is -<code>pxx->procs->virtu(pxx)</code>.</li> - -<li>The procedures are defined in a structure of type -<code>xxx_procs</code> as above. The structure definition of -<code>xxx_t</code> includes a member defined as -<code>xxx_procs procs</code> (always named <code>procs</code>). -The construct for calling the virtual procedure is -<code>pxx->procs.virtu(pxx)</code>.</li> - -<li>The procedures are not defined in a separate structure: each procedure -is a separate member of <code>xxx_t</code>. The construct for calling -the virtual procedure is <code>pxx->virtu(pxx)</code>.</li> - -<li>The procedures are defined in a structure of type -<code>xxx_procs</code> as above. The structure definition of -<code>xxx_t</code> includes a member defined as -<code>xxx_procs procs[1]</code> (always named -<code>procs</code>). The construct for calling the virtual procedure is -again <code>pxx->procs->virtu(pxx)</code>.</li> - -</ol> - -<p> -Note that in approach 1, the procedures are in a shared constant structure; -in approaches 2 - 4, they are in a per-instance structure that can be -changed dynamically, which is sometimes important.</p> - -<p> -In the present Ghostscript code, approach 1 is most common, followed by 2 -and 3; 4 is not used at all. For new code, you should use 1 or 4: that way, -all virtual procedure calls have the same form, regardless of whether the -procedures are shared and constant or per-instance and mutable.</p> - -<h4>Subclassing</h4> - -<p> -Ghostscript's class mechanism allows for subclasses that can add data -members, or can add procedure members if approach 1 or 3 (above) is used. -Since C doesn't support subclassing, we use a convention to accomplish it. -In the example below, <code>gx_device</code> is the root class; it has a -subclass <code>gx_device_forward</code>, which in turn has a subclass -<code>gx_device_null</code>. First we define a macro for all the members -of the root class, and the root class type. (As for structures in general, -classes need a structure descriptor, as discussed in <a -href="#Structures">Structures</a> above: we include these in the examples -below.)</p> - -<blockquote><code> -#define gx_device_common\<br> - type1 member1;\<br> - </code>...<code><br> - typeN memberN<br> -<br> -typedef struct gx_device_s {<br> - gx_device_common;<br> -} gx_device;<br> -<br> -#define private_st_gx_device() /* in gsdevice.c */\<br> - gs_private_st_</code><whatever><code>(st_gx_device, gx_device,\<br> - "gx_device", device_enum_ptrs, device_reloc_ptrs,\<br> - </code>... additional parameters as needed ...<code>) -</code></blockquote> - -<p> -We then define a similar macro and type for the subclass.</p> - -<blockquote><code> -#define gx_device_forward_common\<br> - gx_device_common;\<br> - gx_device *target<br> -<br> -typedef struct gx_device_forward_s {<br> - gx_device_forward_common;<br> -} gx_device_forward;<br> -<br> -#define private_st_device_forward() /* in gsdevice.c */\<br> - gs_private_st_suffix_add1(st_device_forward, gx_device_forward,\<br> - "gx_device_forward", device_forward_enum_ptrs, device_forward_reloc_ptrs,\<br> - gx_device, target) -</code></blockquote> - -<p> -Finally, we define a leaf class, which doesn't need a macro because we don't -currently subclass it. (We can create the macro later if needed, with no -changes anywhere else.) In this particular case, the leaf class has no -additional data members, but it could have some.</p> - -<blockquote><code> -typedef struct gx_device_null_s {<br> - gx_device_forward_common;<br> -};<br> -<br> -#define private_st_device_null() /* in gsdevice.c */\<br> - gs_private_st_suffix_add0_local(st_device_null, gx_device_null,\<br> - "gx_device_null", device_null_enum_ptrs, device_null_reloc_ptrs,\<br> - gx_device_forward) -</code></blockquote> - -<p> -Note that the above example is <strong>not</strong> the actual definition of -the <code>gx_device</code> structure type: the actual type has some -additional complications because it has a finalization procedure. See <a -href="../base/gxdevcli.h">base/gxdevcli.h</a> for the details.</p> - -<p> -If you add members to a root class (such as <code>gx_device</code> in -this example), or change existing members, do this in the -<code>gx_device_common</code> macro, not the <code>gx_device</code> -structure definition. Similarly, to change the -<code>gx_device_forward</code> class, modify the -<code>gx_device_forward_common</code> macro, not the structure -definition. Only change the structure definition if the class is a leaf -class (one with no <code>_common</code> macro and no possibility of -subclassing), like <code>gx_device_null</code>.</p> - -<h3><a name="Error_handling"></a>Error handling</h3> - -<p> -Every caller should check for error returns and, in general, propagate them -to <b>its</b> callers. By convention, nearly every procedure returns an -<code>int</code> to indicate the outcome of the call:</p> - -<blockquote> -<table> -<tr> - <td align="right">< 0</td> - <td colspan="2">Error return</td> -</tr> -<tr> - <td align="right">0</td> - <td colspan="2">Normal return</td> -</tr> -<tr> - <td align="right">> 0</td> - <td colspan="2">Non-error return other than the normal case</td> -</tr> -</table> -</blockquote> - -<p> -To make a procedure generate an error and return it, as opposed to -propagating an error generated by a lower procedure, you should use</p> - -<blockquote> -<code>return_error(</code><em>error_number</em><code>);</code> -</blockquote> - -<p> -Sometimes it is more convenient to generate the error in one place and -return it in another. In this case, you should use</p> -<blockquote> -<code>code = gs_note_error(</code><em>error_number</em><code>);</code><br> -...<br> -<code>return code;</code> -</blockquote> - -<p> -In executables built for debugging, the <code>-E</code> (or -<code>-Z#</code>) command line switch causes <code>return_error</code> -and <code>gs_note_error</code> to print the error number and the source -file and line: this is often helpful for identifying the original cause of -an error.</p> - -<p> -See the file <a href="../base/gserrors.h">base/gserrors.h</a> for the error -return codes used by the graphics library, most of which correspond directly -to PostScript error conditions.</p> - -<!-- [2.0 end contents] ==================================================== --> -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small></p> - -<p> -This software is provided AS-IS with no warranty, either express or -implied.</p> - -<p>This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.</p> - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Commprod.htm b/doc/Commprod.htm deleted file mode 100644 index 594e4f8d..00000000 --- a/doc/Commprod.htm +++ /dev/null @@ -1,318 +0,0 @@ -<!doctype html> -<html> -<head> -<meta charset="UTF-8"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet"> -<link rel="shortcut icon" type="image/png" href="../../images/favicon.png"> -<title>Conditions on Distributing Ghostscript in a Commercial Context</title> - <!-- Originally: commprod.txt --> -<link href="style.css" rel="stylesheet" type="text/css"> -<link href="gs-style.css" rel="stylesheet" type="text/css"> -</head> - -<body> - - <div class="header"> - <div class="row"> - <div class="col-lt-6 logo"><a href="https://www.ghostscript.com/"><img src="images/ghostscript_logo.png" width="108" height="119" alt=""></a></div> - <div class="col-6"><div class="row"><div class="artifexlogo"><a href="https://artifex.com" target="_blank"><img src="images/Artifex_logo.png" width="194" height="40" alt=""></a></div> - <div class="col-12"><div class="button button1"><a href="https://artifex.com/contact-us/" title="Contact Us" target="_blank">Contact Us</a></div> - <div class="button button2 hidden-xs"><a href="https://www.ghostscript.com/download.html" title="Download">Download</a></div></div></div> - </div> - </div> - </div> - - <div class="banner"> - <div class="row"> - <div class="col-12">Conditions on Distributing Ghostscript in a Commercial Context</div> - </div> - </div> - - <div class="main"> - <div class="row"> - <div id="sidebar"> - <div class="sidebar-item"></div> - <div class="col-2 leftnav"> -<ul> - <li><a href="https://www.ghostscript.com/">Home</a></li> - <li><a href="https://www.ghostscript.com/license.html">Licensing</a></li> - <li><a href="https://www.ghostscript.com/releases.html">Releases</a></li> - <li><a href="https://www.ghostscript.com/documentation.html" title="Documentation">Documentation</a></li> - <li><a href="https://www.ghostscript.com/download.html" title="Download">Download</a></li> - <li><a href="https://www.ghostscript.com/performance.html" title="Performance">Performance</a></li> - <li><a href="http://jbig2dec.com/" title="jbig2dec">jbig2dec</a></li> - <li><a href="http://git.ghostscript.com/?p=ghostpdl.git;a=summary">Source</a></li> - <li><a href="http://bugs.ghostscript.com/">Bugs</a></li> - <li><a href="https://www.ghostscript.com/faq.html" title="FAQ">FAQ</a></li> - </ul> - </div> - </div> - <div class="col-10 page"> - -<!--START EDITING HERE--> - -<h2>Table of contents</h2> - -<ul> -<li><a href="#GPL">The GNU Affero General Public License (AGPL)</a></li> -<li><a href="#examples">Distribution examples</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p> -This document sets forth the conditions under which Ghostscript may be -distributed in a commercial context: under a written license from <a -href="http://artifex.com/">Artifex Software</a> Inc., the copyright -holder's exclusive commercial licensing partner, or under certain other -very limited conditions.</p> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<!-- [1.0 end visible header] ============================================== --> - -<hr> - -<!-- [2.0 begin contents] ================================================== --> - -<p> -The use of the public-access "free" versions of Ghostscript</p> - -<h2><a name="GPL"></a>The GNU Affero General Public License (AGPL)</h2> - -<p> -Ghostscript is a copyrighted work whose copyright is owned by -Artifex Software, Inc. -Some versions of Ghostscript are distributed freely under the name -GPL Ghostscript or (for older versions) GNU Ghostscript; these versions -are distributed with a license called the GNU -<a href="http://www.gnu.org/licenses/agpl-3.0.html">Affero General Public License</a> -(also known as the "AGPL", or "copyleft"), which allows gratis and commercial distribution under certain conditions, most -particularly, source complete source disclosure. -</p> - -<p> -Versions of Ghostscript between version 4.03 and 8.54 were also -distributed under a more restrictive license disallowing commercial -redistribution entirely. These versions were labelled "AFPL Ghostsript" or -just "Ghostscript", and were governed by the Aladdin Free Public License. -</p> - -<p> -The full AGPL is included under the name -<code>COPYING</code> in the GPL Ghostscript fileset, and -can also be obtained directly from the Free Software Foundation:</p> - -<blockquote><address><a name="FSF_address"></a> -Free Software Foundation, Inc. (FSF)<br> -59 Temple Place, Suite 330<br> -Boston, MA 02111-1307 U.S.A.<br> -+1-617-542-5942 telephone<br> -+1-617-542-2652 fax (including Japan):<br> -<a href="mailto:gnu@gnu.org">gnu@gnu.org</a><br> -<a href="http://www.gnu.org/">http://www.gnu.org/</a> -</address></blockquote> - -<p> -The AGPL gotten directly from the FSF or the contents of the -<code>COPYING</code> file are authoritative, but for those -unfamiliar with the AGPL, we now summarize its provisions.</p> - -<p>1. Anyone may copy and distribute GPL Ghostscript (both source -and object code), but they must distribute the source code as well as -the object code (or, if they distribute only the object code, they must -include an offer in writing to provide the source code at no more than -reproduction cost), keep all copyright and other notices, and include the -AGPL with the copies. (Note that this allows anyone receiving such a copy -to distribute it freely as well.)</p> - -<p>2. Anyone may modify GPL Ghostscript, but the provisions of (1) -apply to modified or derived works as well.</p> - -<p> -Provision (2) effectively prevents the development of proprietary commercial -products that incorporate GPL Ghostscript without a commercial license -as a part, since these are "derived works" in the legal sense.</p> - -<p><strong> IF YOUR ENTIRE APPLICATION IS LICENSED TO THE PUBLIC -UNDER EITHER -THE AFPL OR THE GNU AGPL, YOU CAN DISTRIBUTE AFPL GHOSTSCRIPT OR GNU -GHOSTSCRIPT, RESPECTIVELY, WITH YOUR APPLICATION WITHOUT A COMMERCIAL -LICENSE . . .</strong></p> - -<p> If your application, including all of its source code, is -licensed -to the public under the GNU AGPL, you are authorized to ship -GPL Ghostscript with your application -under the terms of those license agreements. You do not need a -commercial license from Artifex. The terms of the GNU AGPL -include the requirement that your application be licensed as a whole at -no charge to all third parties. Moreover, the entire application must be -licensed to the public under the GNU AGPL or AFPL respectively.</p> - -<p> IF YOUR APPLICATION IS NOT LICENSED TO THE PUBLIC UNDER -THE GNU AGPL AND YOU PLAN TO DISTRIBUTE GHOSTSCRIPT SOFTWARE. . .</p> - -<p> If your application (including its source code) is not licensed -to the public under the GNU AGPL, you are not authorized to ship -GPL Ghostscript with your application under the terms of the GNU AGPL -if any one of the following is true:</p> - -<ul> -<li> your application contains a copy of some or all of GPL -Ghostscript;</li> -<li> your application is derived from, is based on, or constitutes a -revision of some or all of AGPL or Ghostscript;</li> -<li> your application includes one or more functions that use some or -all of AGPL or Ghostscript.</li> -</ul> - -<p> - These criteria apply to your application as a whole. Even if only -one section of your application satisfies one of these criteria, you are -not authorized to ship GPL Ghostscript with your application -unless your application, including all of its source code, is licensed -to the public under the GNU AGPL.</p> - -<p> - If your application (including its source code) is NOT licensed to -the public under the GNU AGPL and you intend to distribute -Ghostscript (either internally or externally) for use with and usable by -your application, you MUST first obtain a commercial license from -Artifex.</p> -<hr> -<h2><a name="examples"></a>Examples of Distribution</h2> - -<p> - Some examples of distribution requiring a commercial license -include:</p> -<p> - 1. Distributing Ghostscript (or any component thereof) within your -non-GNU AGPL application.</p> -<p> - 2. Distributing Ghostscript on the same media with your -non-GNU AGPL application for use with and by your application.</p> -<p> - 3. Distributing Ghostscript embedded within hardware.</p> - - - -<p> -Questions have arisen at times in particular cases regarding provision (3) -as to whether GPL Ghostscript is "aggregated" with other parts of a -commercial product, or whether the product has become a "derived work." -Normally, combining GPL Ghostscript with another piece of software -creates -a "derived work"; we consider GPL Ghostscript to be "aggregated" with -another piece of software, which we will refer to as "the application", -only if all of the following conditions are met:</p> - -<ul> -<li> The code and documentation for GPL Ghostscript are physically -separated from the code and documentation for the application. For -electronic form, it is both necessary and sufficient to put the GNU -Ghostscript code and documentation in their own directory tree(s).</li> - -<li> GPL Ghostscript, as delivered with the application, is usable -independently of the application. More precisely, if a user deletes from -the computer system all files delivered with the application except those -in the GPL Ghostscript directories, the user will still be able to use -GPL Ghostscript as described in GPL Ghostscript's documentation. Among -other things, this requires that GPL Ghostscript not call any routines -in the application, and not require any data or other files supplied as -part of the application.</li> - -<li> The application calls GPL Ghostscript in a way that allows an -ordinary user to substitute another program for GPL Ghostscript. -(Typically this requires use of a shell script or batch file, or a -system call like "<code>exec</code>".) More precisely, if the user -deletes from the computer system all the files in the GPL Ghostscript -directories, and replaces the GPL Ghostscript executable with another -program with the same name and conforming to the same documentation, the -application will continue to work with it. One implication of this is -that the GPL Ghostscript documentation must specify all properties of -GPL Ghostscript on which the application relies; for example, if GPL -Ghostscript has been modified by the addition of command line switches -or language elements such as new operators, the documentation must -describe any such additions that the application uses.</li> - -<li> The conditions of the GNU AGPL are met with respect to GPL Ghostscript, -including the requirement for propagation of the AGPL and the requirement -for delivering (or an offer to deliver) source code.</li> -</ul> - -<p> -Regarding this last point, the AGPL clearly intends that if the distributor -only offers to provide the GPL Ghostscript source code (as opposed to -actually distributing the source code with every copy of the application), -then they must deliver the source code in a timely way to anyone -requesting it.</p> - -<p> -The AGPL makes it clear that if someone receives GPL Ghostscript only in -its AGPL-licensed form, they only have a right to distribute it if they -comply with the AGPL. Artifex Software, Inc., as the copyright holder, -takes this requirement very seriously, and will, if necessary, take -legal action to ensure that anyone distributing GPL Ghostscript with the -AGPL complies with the conditions set forth above.</p> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2021 Artifex Software, Inc. All rights -reserved.</small></p> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. This software is distributed under license and may not be copied, -modified or distributed except as expressly authorized under the terms -of the license contained in the file LICENSE in this distribution. For more information about licensing, please visit -http://www.artifex.com/licensing/or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861.</p> - -<p> -<small>Ghostscript version 9.55.0, 27 September 2021 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - - </div> - </div> - </div> - - <div class="footer"> - <div class="row"> - <div class="col-7 footleft"> - <ul> - <li><a href="https://artifex.com/contact-us/" target="blank">CONTACT US</a></li> - <li><a href="https://artifex.com/about-us/" target="blank">ABOUT</a></li> - <li><a href="https://ghostscript.com/security.html">SECURITY</a></li> - </ul> - </div> - <div class="col-1 footcenter"> - <ul> - <li><a href="https://artifex.com/support/" target="blank">SUPPORT</a></li> - <li><a href="https://artifex.com/blog/artifex/" target="blank">BLOG</a></li> - <li><a href="https://artifex.com/privacy-policy/" target="blank">PRIVACY</a></li> - </ul> - </div> - <div class="col-ft-3 footright"><img src="images/Artifex_logo.png" width="194" height="40" alt=""/> <br> - © Copyright 2019-2021 Artifex Software, Inc. <br> - All rights reserved. - </div> - </div> - </div> - - <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> - <script src="index.js"></script> -</body> -</html> diff --git a/doc/DLL.htm b/doc/DLL.htm deleted file mode 100644 index 325b87e2..00000000 --- a/doc/DLL.htm +++ /dev/null @@ -1,754 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>How to Use the Ghostscript Dynamic Link Library (DLL)</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>How to Use the Ghostscript Dynamic Link Library (DLL)</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#DLL">What is the Ghostscript DLL?</a></li> - <li><a href="#Common_functions">Platform-independent DLL functions</a></li> - <li> - <ul> - <li><a href="#revision"><code>gsdll_revision()</code></a></li> - <li><a href="#init"><code>gsdll_init()</code></a></li> - <li><a href="#execute_begin"><code>gsdll_execute_begin()</code></a></li> - <li><a href="#execute_cont"><code>gsdll_execute_cont()</code></a></li> - <li><a href="#execute_end"><code>gsdll_execute_end()</code></a></li> - <li><a href="#exit"><code>gsdll_exit()</code></a></li> - <li><a href="#lock_device"><code>gsdll_lock_device()</code></a></li> - </ul> - </li> - <li><a href="#Callback">Callback function</a></li> - <li><a href="#OS2_device">Ghostscript DLL device for OS/2</a></li> - <li> - <ul> - <li><a href="#OS2_bmp"><code>gsdll_get_bitmap()</code></a></li> - <li><a href="#OS2_example">Example DLL usage for OS/2</a></li> - </ul> - </li> - <li><a href="#Win_device">Ghostscript DLL device for MS Windows</a></li> - <li> - <ul> - <li><a href="#Win_copydib"><code>gsdll_copy_dib()</code></a></li> - <li><a href="#Win_copypalette"><code>gsdll_copy_palette()</code></a></li> - <li><a href="#Win_draw"><code>gsdll_draw()</code></a></li> - <li><a href="#Win_get_row"><code>gsdll_get_bitmap_row()</code></a></li> - </ul> - </li> - <li><a href="#Win16">Ghostscript DLL Device for 16-bit MS Windows</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. - -<p> -<b>WARNING: The API described in this document is obsolete and will -be removed in the future.</b> -The current Ghostscript Interpreter API -is described in <a href="API.htm">API.htm</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="DLL"></a>What is the Ghostscript DLL?</h2> - -<p> -For the OS/2, Win16 and Win32 platforms, Ghostscript is built as a dynamic -link library (DLL), and to provide the interface described in the <a -href="Use.htm">usage documentation</a>, a smaller independent executable -(<code>.EXE</code>) loads this DLL, which provides all the interaction -with the windowing system, including image windows and, if necessary, a -text window. This document describes the DLL interface, which consists of -eight main functions, <a href="#functions">seven platform-independent -ones</a> provided by the DLL and one, <a href="#Callback">the callback -function</a>, provided by the caller. The DLL provides some other -platform-specific functions for display devices. - -<p> -The DLL's name and characteristics differ among the three platforms: - -<ul> -<li>The <a href="#OS2_device">OS/2 DLL <code>GSDLL2.DLL</code></a> has -MULTIPLE NONSHARED data segments and can be called by multiple programs -simultaneously.</li> - -<li>The <a href="#Win_device">Win32 DLL <code>GSDLL32.DLL</code></a> has -MULTIPLE NONSHARED data segments. Under Win32s it can be used by only one -program at a time, but under Windows 95/98 or Windows NT it can be called by -multiple programs simultaneously.</li> - -<li>The <a href="#Win16">Win16 DLL <code>GSDLL16.DLL</code></a> is a -large-memory model DLL with far static data. Due to the limitations of -16-bit MS Windows -- Windows 3.n -- the DLL can be used by only one program -at a time.</li> -</ul> - -<p> -The source for the executable is in <code>dp</code>*.* (OS/2) and -<code>dw</code>*.* (Windows). See these source files for examples of -how to use the DLL. - -<hr> - -<h2><a name="Common_functions"></a>Platform-independent DLL functions</h2> - -<p> -The seven functions provided by the DLL are -<ul> -<li><code>int GSDLLAPI <a href="#revision">gsdll_revision</a>(char **product, char **copyright, long *gs_revision, long *gs_revisiondate)</code></li> -<li><code>int GSDLLAPI <a href="#init">gsdll_init</a>(GSDLL_CALLBACK callback, HWND hwnd, int argc, char *argv[]);</code></li> -<li><code>int GSDLLAPI <a href="#execute_begin">gsdll_execute_begin</a>(void);</code></li> -<li><code>int GSDLLAPI <a href="#execute_cont">gsdll_execute_cont</a>(const char *str, int len);</code></li> -<li><code>int GSDLLAPI <a href="#execute_end">gsdll_execute_end</a>(void);</code></li> -<li><code>int GSDLLAPI <a href="#exit">gsdll_exit</a>(void);</code></li> -<li><code>int GSDLLAPI <a href="#lock_device">gsdll_lock_device</a>(unsigned char *device, int flag);</code> - -<p> -where <code>GSDLLAPI</code> is defined under OS/2 as - -<blockquote><code> -#define GSDLLAPI -</code></blockquote> - -<p> -and under MS Windows as - -<blockquote><code> -#define GSDLLAPI CALLBACK _export -</code></blockquote> -</li> -</ul> - -<h3><a name="revision"></a><code>gsdll_revision()</code></h3> - -<blockquote> -This function returns the revision numbers and strings of the Ghostscript -DLL; you should call it before <code>gsdll_init()</code> to make sure -that the correct version of the Ghostscript DLL has been loaded. For -example - -<blockquote> -<pre>char *product; -char *copyright; -long revision; -long revisiondate; -gsdll_revision(&product, &copyright, &revision, &revisiondate); -</pre></blockquote> - -<p> -You may use <code>NULL</code> pointers if you do not want a particular -value. -</blockquote> - -<h3><a name="init"></a><code>gsdll_init()</code></h3> - -<blockquote> -<code>gsdll_init()</code> must be called after loading the DLL and -before executing any Ghostscript commands. The arguments are the address -of the callback function, a parent window handle, the count of arguments -and an array of pointers to the arguments. For example - -<blockquote> -<pre>char *argv[5]; -argv[0] = "gswin.exe"; -argv[1] = "-Ic:\\gs;c:\gs\\fonts"; -argv[2] = "-dNOPAUSE", -argv[3] = "-sDEVICE=djet500", -argv[4] = NULL; -argc = 4; - -code = gsdll_init(gsdll_callback, hwnd, argc, argv); -</pre></blockquote> - -<p> -<code>hwnd</code> is used as the parent window handle for any windows -created by Ghostscript. <code>hwnd</code> may be <code>NULL</code> -if the caller has no windows, but if it is <code>NULL</code>, you should -avoid using devices which may open windows. - -<p> -A return code of 0 (zero) indicates no errors, and the code may now call -<code>gsdll_execute_begin()</code> or <code>gsdll_exit()</code>. If -the return value is non-zero then <code>gsdll_exit()</code> must not be -called. - -<p> -A return value of <code>GSDLL_INIT_QUIT</code> indicates that one of the -command line files or arguments called "<code>quit</code>", or that -Ghostscript was reading stdin and reached end-of-file. This is not an -error. <code>gsdll_exit()</code> must not be called. - -<p> -A return value of <code>GSDLL_INIT_IN_USE</code> indicates that the DLL -is in use by another application (Windows 3.1 only). The DLL should be -immediately unloaded (or the caller terminated). -<code>gsdll_exit()</code> must not be called. -</blockquote> - -<h3><a name="execute_begin"></a><code>gsdll_execute_begin()</code></h3> - -<blockquote> -This must be called after <code>gsdll_init()</code> and before -<code>gsdll_execute_cont()</code>. -</blockquote> - -<h3><a name="execute_cont"></a><code>gsdll_execute_cont()</code></h3> - -<blockquote> -After successfully calling <code>gsdll_init()</code> and -<code>gsdll_execute_begin()</code>, commands may be given to Ghostscript -with <code>gsdll_execute_cont()</code>. Examples are: - -<blockquote> -<pre>char *command = "1 2 add == flush\n"; -code = gsdll_execute_cont(command, strlen(command)); -command = "qu" -code = gsdll_execute_cont(command, strlen(command)); -command = "it\n" -code = gsdll_execute_cont(command, strlen(command)); -</pre> - -<a name="cont_returns"></a> -<table> -<tr> - <th colspan="2">Return codes from gsdll_execute_cont()</th> -</tr> -<tr> - <th align="left">Code</th> - - <th align="left">Status</th> -</tr> -<tr> - <td align="left">0</td> - - <td>No errors</td> - </tr> -<tr> - <td align="left">< 0</td> - - <td>Error</td> - </tr> -<tr> - <td align="left"><= -100</td> - - <td>"<code>quit</code>" has been executed, or fatal error. -<code>gsdll_exit()</code> must then be called: do not call -<code>gsdll_execute_end()</code>.</td> - </tr> -</table> -</blockquote> - -<code>gsdll_execute_cont()</code> -does not flush stdio, so if you want to see output from Ghostscript you -must do this explicitly as shown in the example above. - -<p> -When executing a string with <code>gsdll_execute_cont()</code>, -<code>currentfile</code> is the input from -<code>gsdll_execute_cont()</code>. Reading from <code>%stdin</code> -uses the callback. - -<p> -Please note that there is a 64 KB length limit on the passed string. -If you have more than 65535 bytes of input to process at a given time, -it must be split into separate smaller buffers, each passed on a -separate call. - -</blockquote> - -<h3><a name="execute_end"></a><code>gsdll_execute_end()</code></h3> - -<blockquote> -If <code>gsdll_execute_cont()</code> did not return an error, then -<code>gsdll_execute_end()</code> must be called after -<code>gsdll_execute_cont()</code> and before -<code>gsdll_exit()</code>. -</blockquote> - -<h3><a name="exit"></a><code>gsdll_exit()</code></h3> - -<blockquote> -Call gsdll_exit() to terminate the Ghostscript DLL. It must be called if a -fatal error has occurred; see the <a href="#cont_returns">return value -of <code>gsdll_execute_cont()</code></a>. After calling -<code>gsdll_exit()</code>, there are two options: - -<ul> -<li>Unload the DLL, either by terminating the application or by -calling <code>DosFreeModule</code> (OS/2) or <code>FreeLibrary</code> (MS Windows). - -<li>Call <code>gsdll_init()</code> again to restart Ghostscript. -</ul> -</blockquote> - -<h3><a name="lock_device"></a><code>gsdll_lock_device()</code></h3> - -<blockquote> -Since the caller may be multithreaded, a lock is needed to control access -to the display device, and <code>gsdll_lock_device()</code> provides that -locking. - -<blockquote> -<pre>int gsdll_lock_device(unsigned char *device, int flag); - /* Lock the device if flag = TRUE */ - /* Unlock the device if flag = FALSE */ - /* device is a pointer to Ghostscript os2dll or mswindll device */ - /* from GSDLL_DEVICE message. */ - /* Return value is the lock count. */ -</pre> - -<table> -<tr> - <th colspan="2">Locking and unlocking devices</th> - </tr> -<tr> - <td>To lock a device</td> - - <td><code>gsdll_lock_device(device, 1)</code>;</td> - </tr> -<tr> - <td>To unlock a device</td> - - <td><code>gsdll_lock_device(device, 0)</code>;</td> - </tr> -</table> -</blockquote> - -<p> -This function is typically used to lock the device while repainting a -window or copying the device bitmap to the clipboard. Ghostscript may draw -into the device bitmap or update the palette entries while the device is -locked by the caller, but locking the device prevents the Ghostscript DLL -from closing the device or changing its size or depth. - -<p> -Under OS/2, Windows 95/98 and Windows NT, this lock is implemented using a -mutual exclusion semaphore (mutex). The return value is the lock count, -which is either 0 ("unlocked") or 1 ("locked"). The function blocks until -the device is locked by the caller. - -<p> -Under Win16 or Win32s, <code>gsdll_lock_device()</code> always returns -immediately with a lock count as its return value. A lock count of 2 or -more is definite indication of an error, probably calling the function -twice. Access to the device should be controlled by checking the Windows -message queue only when the bitmap is not being accessed. -</blockquote> - -<hr> - -<h2><a name="Callback"></a>Callback function</h2> - -<blockquote> -As an argument to <a href="#init"><code>gsdll_init()</code></a> the -caller must provide a callback function which the DLL invokes for stdio and -to notify the caller about device events. The function provided by the -caller has this prototype: - -<blockquote><code> -int gsdll_callback(int message, char *str, unsigned long count); -</code></blockquote> - -<p> -The Pascal calling convention is not used. An example callback function -is: - -<blockquote> -<pre>int -gsdll_callback(int message, char *str, unsigned long count) -{ -char *p; - switch (message) { - case GSDLL_STDIN: - p = fgets(str, count, stdin); - if (p) - return strlen(str); - else - return 0; - case GSDLL_STDOUT: - if (str != (char *)NULL) - fwrite(str, 1, count, stdout); - return count; - case GSDLL_DEVICE: - fprintf(stdout,"Callback: DEVICE %p %s\n", str, - count ? "open" : "close"); - break; - case GSDLL_SYNC: - fprintf(stdout,"Callback: SYNC %p\n", str); - break; - case GSDLL_PAGE: - fprintf(stdout,"Callback: PAGE %p\n", str); - break; - case GSDLL_SIZE: - fprintf(stdout,"Callback: SIZE %p width=%d height=%d\n", str, - (int)(count & 0xffff), (int)((count>>16) & 0xffff) ); - break; - case GSDLL_POLL: - return 0; /* no error */ - default: - fprintf(stdout,"Callback: Unknown message=%d\n",message); - break; - } - return 0; -} -</pre> - -<table> - <tr> - <th colspan="3">Messages used by callback</th> - </tr> -<tr> - <th align="left">Symbol</th> - - <th align="left">Value</th> - - <th align="left">Use</th> - </tr> -<tr> - <td><code>GSDLL_STDIN</code></td> - - <td>1</td> - - <td>get <code>count</code> characters to <code>str</code> from stdin, return number of characters read</td> - </tr> -<tr> - <td><code>GSDLL_STDOUT</code></td> - - <td>2</td> - - <td>put <code>count</code> characters from <code>str</code> - to stdout, return number of characters written</td> - </tr> -<tr> - <td><code>GSDLL_DEVICE</code></td> - - <td>3</td> - - <td>device <code>str</code> has been opened if - <code>count</code> = 1, closed if - <code>count</code> = 0</td> - </tr> -<tr> - <td><code>GSDLL_SYNC</code></td> - - <td>4</td> - - <td>sync_output for device <code>str</code></td> - </tr> -<tr> - <td><code>GSDLL_PAGE</code></td> - - <td>5</td> - - <td>output_page for device <code>str</code></td> - </tr> -<tr> - <td><code>GSDLL_SIZE</code></td> - - <td>6</td> - - <td>resize for device <code>str</code>: - LOWORD(<code>count</code>) is new <code>xsize</code>, - HIWORD(<code>count</code>) is new <code>ysize</code></td> - </tr> -<tr> - <td><code>GSDLL_POLL</code></td> - - <td>7</td> - - <td>Called from <code>gp_check_interrupt()</code><br> - Can be used by the caller to poll the message queue. - Normally returns 0. To abort - <code>gsdll_execute_cont()</code>, return a non-zero - error code until <code>gsdll_execute_cont()</code> - returns.</td> - </tr> -</table> -</blockquote> -</blockquote> - -<hr> - -<h2><a name="OS2_device"></a>Ghostscript DLL device for OS/2</h2> - -<p> -The <code>os2dll</code> device is provided in the Ghostscript DLL for -use by the caller. No drawing facilities are provided by the DLL because -the DLL may be loaded by a text-only (non-PM) application. The caller is -notified via the <code>gsdll_callback()</code> when a new -<code>os2dll</code> device is opened or closed -(<code>GSDLL_DEVICE</code>), when the window should be redrawn -(<code>GSDLL_SYNC</code> or <code>GSDLL_PAGE</code>) or when the -bitmap size changes (<code>GSDLL_SIZE</code>). -Note that more than one <code>os2dll</code> device may be opened. - -<h3><a name="OS2_bmp"></a><code>gsdll_get_bitmap()</code></h3> - -<blockquote> -<code>gsdll_get_bitmap()</code> returns a pointer to a bitmap in BMP -format. The <code>os2dll</code> device draws into this bitmap. - -<blockquote> -<pre>unsigned long gsdll_get_bitmap(unsigned char *device, unsigned char **pbitmap); - /* return in pbitmap the address of the bitmap */ - /* device is a pointer to Ghostscript os2dll device from GSDLL_DEVICE message */ -</pre></blockquote> - -<p> -The caller can then display the bitmap however it likes, but should lock -the bitmap with <code>gsdll_lock_device()</code> before painting from -it, and unlock it afterwards. The bitmap address does not change until the -<code>os2dll</code> device is closed; however the bitmap size and -palette may change whenever the bitmap is not locked. -</blockquote> - -<h3><a name="OS2_example"></a>Example DLL usage for OS/2</h3> - -<p> -The example here shows a minimal usage of the Ghostscript DLL under OS/2. -The sample callback function above is needed. - -<blockquote> -<pre>#define INCL_DOS -#include <os2.h> -#include <stdio.h> -#include "gsdll.h" - -PFN_gsdll_init pgsdll_init; -PFN_gsdll_execute_begin pgsdll_execute_begin; -PFN_gsdll_execute_cont pgsdll_execute_cont; -PFN_gsdll_execute_end pgsdll_execute_end; -PFN_gsdll_exit pgsdll_exit; - -HMODULE hmodule_gsdll; -char buf[256]; - -int -main(int argc, char *argv[]) -{ -int code; -APIRET rc; - if (!DosLoadModule(buf, sizeof(buf), "GSDLL2", &hmodule_gsdll)) { - fprintf(stderr, "Loaded GSDLL2\n"); - DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_init", (PFN *)(&pgsdll_init)); - DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_begin", (PFN *)(&pgsdll_execute_begin)); - DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_cont", (PFN *)(&pgsdll_execute_cont)); - DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_end", (PFN *)(&pgsdll_execute_end)); - DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_exit", (PFN *)(&pgsdll_exit)); - } - else { - fprintf(stderr, "Can't load GSDLL2\n"); - } - - code = (*pgsdll_init)(gsdll_callback, NULL, argc, argv); - fprintf(stdout,"gsdll_init returns %d\n", code); - code = (*pgsdll_execute_begin)(); - if (code==0) { - while (fgets(buf, sizeof(buf), stdin)) { - code = (*pgsdll_execute_cont)(buf, strlen(buf)); - fprintf(stdout,"gsdll_execute returns %d\n", code); - if (code < 0) - break; - } - if (!code) - code = (*pgsdll_execute_end)(); - code = (*pgsdll_exit)(); - fprintf(stdout,"gsdll_exit returns %d\n", code); - } - rc = DosFreeModule(hmodule_gsdll); - fprintf(stdout,"DosFreeModule returns %d\n", rc); - return 0; -} -</pre></blockquote> - -<hr> - -<h2><a name="Win_device"></a>Ghostscript DLL device for MS Windows</h2> - -<p> -The <code>mswindll</code> device is provided in the Ghostscript DLL for -use by the caller. The caller is notified via the -<code>gsdll_callback()</code> when a new <code>mswindll</code> device -is opened or closed (<code>GSDLL_DEVICE</code>), when the window should -be redrawn (<code>GSDLL_SYNC</code> or <code>GSDLL_PAGE</code>) or -when the bitmap size changes (<code>GSDLL_SIZE</code>). Note that more -than one <code>mswindll</code> device may be opened. - -<p> -Four DLL functions are available to use the <code>mswindll</code> -device. - -<h3><a name="Win_copydib"></a><code>gsdll_copy_dib()</code></h3> - -<blockquote> -Copy the <code>mswindll</code> bitmap to the clipboard. - -<blockquote> -<pre>HGLOBAL GSDLLAPI gsdll_copy_dib(unsigned char *device); - /* make a copy of the device bitmap and return shared memory handle to it */ - /* device is a pointer to Ghostscript device from GSDLL_DEVICE message */ -</pre></blockquote> -</blockquote> - -<h3><a name="Win_copypalette"></a><code>gsdll_copy_palette()</code></h3> - -<blockquote> -Copy the <code>mswindll</code> palette to the clipboard. - -<blockquote> -<pre>HPALETTE GSDLLAPI gsdll_copy_palette(unsigned char *device); -/* make a copy of the device palette and return a handle to it */ -/* device is a pointer to Ghostscript device from GSDLL_DEVICE message */ -</pre></blockquote> -</blockquote> - -<h3><a name="Win_draw"></a><code>gsdll_draw()</code></h3> - -<blockquote> -Display output from the <code>mswindll</code> device. The caller should -create a window and call <code>gsdll_draw()</code> in response to the -<code>WM_PAINT</code> message. The device context <code>hdc</code> -must be for a device because <code>SetDIBitsToDevice()</code> is used. - -<blockquote> -<pre>void GSDLLAPI gsdll_draw(unsigned char *device, HDC hdc, - LPRECT dest, LPRECT src); -/* copy the rectangle src from the device bitmap */ -/* to the rectangle dest on the device given by hdc */ -/* hdc must be a device context for a device (NOT a bitmap) */ -/* device is a pointer to Ghostscript device from GSDLL_DEVICE message */ -</pre></blockquote> -</blockquote> - -<h3><a name="Win_get_row"></a><code>gsdll_get_bitmap_row()</code></h3> - -<blockquote> -Get a BMP header, a palette, and a pointer to a row in the bitmap. This -function exists to allow the bitmap to be copied to a file or structured -storage without the overhead of having two copies of the bitmap in memory -at the same time. - -<p> -Ghostscript can change the palette while the device is locked. Do not call -this function while Ghostscript is busy. - -<blockquote> -<pre>int GSDLLAPI gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih, - LPRGBQUAD prgbquad, LPBYTE *ppbyte, unsigned int row) -/* If pbmih nonzero, copy the BITMAPINFOHEADER. - * If prgbquad nonzero, copy the palette. - * number of entries copied is given by pbmih->biClrUsed - * If ppbyte nonzero, return pointer to row. - * pointer is only valid while device is locked - */ -</pre></blockquote> -</blockquote> - -<hr> - -<h2><a name="Win16"></a>Ghostscript DLL Device for 16-bit MS Windows</h2> - -<p> -This platform has the most problems of the three. Support for it may be -dropped in future. - -<p> -The Win16 DLL <code>GSDLL16.DLL</code> is a large-memory model DLL with -far static data. Due to the limitations of 16-bit MS Windows, the DLL can -be used by only one program at a time. - -<p> -However, <code>GSDLL16</code> is marked as having SINGLE SHARED data -segments, allowing multiple applications to load it with no error -indication. (The DLL wouldn't load at all if MULTIPLE NONSHARED was used). -Nonetheless, <b>it cannot be used by more than one application at a -time</b>, so applications loading <code>GSDLL16</code> should check the -return value of <code>gsdll_init()</code>: if this value is non-zero, -then <code>GSDLL16</code> is already in use by another application and -should <b><em>not</em></b> be used: <code>GSDLL16</code> should be -unloaded immediately using <code>FreeLibrary()</code>, or the calling -program should quit without attempting to use the library.. - -<p> -The segmented architecture of the Intel 80286 causes the usual amount of -grief when using <code>GSDLL16</code>. Because the callback is called -from the DLL, which is using a different data segment, the callback must be -declared as <code>_far _export</code>: - -<blockquote> -<pre>int _far _export gsdll_callback(int message, char *str, unsigned long count); -</pre></blockquote> - -<p> -Instead of giving <code>gsdll_init()</code> the address of -<code>gsdll_callback()</code>, it should instead be given the address of -a thunk created by <code>MakeProcInstance</code>. This thunk changes -the data segment back to that used by the caller: - -<blockquote> -<pre>FARPROC lpfnCallback; -lpfnCallback = (FARPROC)MakeProcInstance((FARPROC)gsdll_callback, hInstance); -code = (*pgsdll_init)((GSDLL_CALLBACK)lpfnCallback, NULL, argc, argv); -if (!code) { - fprintf(stderr, "GSDLL16 is already in use\n"); - return -1; -} -</pre></blockquote> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Deprecated.htm b/doc/Deprecated.htm deleted file mode 100644 index 62be1773..00000000 --- a/doc/Deprecated.htm +++ /dev/null @@ -1,5769 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Deprecated Ghostscript Features</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Deprecated Ghostscript Features</h1> - -<h2><a name="toc"></a>Table of contents</h2> - -<ul class="toc"> - <li><a href="#Options">Deprecated Options</a></li> - <li><a href="#HP8_color_inkjet">H-P 8xx, 1100, and 1600 color inkjet printers</a></li> - <li> - <ul> - <li><a href="#HP8_gdevcd8">Drivers contained in <code>gdevcd8.c</code></a></li> - <li><a href="#HP8_further_documentation">Further documentation</a></li> - </ul> - </li> - <li><a href="#HP880_color_inkjet">H-P 812, 815, 832, 880, 882, 895, and 970 color inkjet printers</a></li> - <li> - <ul> - <li><a href="#HP880_gdevcd8">Drivers contained in <code>gdevcd8.c</code></a></li> - <li><a href="#HP880_further_documentation">Further documentation</a></li> - </ul> - </li> - <li><a href="#HP_color_inkjet">Other H-P color inkjet printers</a></li> - <li> - <ul> - <li><a href="#HP_gdevcdj">Drivers contained in <code>gdevcdj.c</code></a></li> - <li><a href="#HP_paper_size">Default paper size</a></li> - <li><a href="#HP_limits">Deskjet physical limits</a></li> - <li><a href="#HP_command_line">Printer properties (command-line parameters)</a></li> - <li> - <ul> - <li><a href="#HP_bpp">Bits per pixel</a></li> - <li><a href="#HP_deskjet_properties">Deskjet properties</a></li> - <li><a href="#HP_paintjet_properties">Paintjet XL300 / Paintjet XL properties</a></li> - </ul> - </li> - <li><a href="#HP_gamma">Gamma correction</a></li> - <li><a href="#HP_resolution_enhance">HP's resolution-enhanced mode for Inkjet printers</a></li> - <li><a href="#HP_tips">General tips</a></li> - </ul> - </li> - - <li><a href="#BJC_8200">Canon BJC-8200 printer</a></li> - <li><a href="#BJC">Other Canon BubbleJet (BJC) printers</a></li> - <li> - <ul> - <li><a href="#BJC_history">History</a></li> - <li><a href="#BJC_build">Configuring and building the BJC drivers</a></li> - <li> - <ul> - <li><a href="#BJC_defaults">Modify values in <code>gdevbjc.h</code></a></li> - <li><a href="#BJC_CMYK_RGB">CMYK-to-RGB color conversion</a></li> - <li><a href="#BJC_vertical_centering">Vertical centering of the printable area</a></li> - <li><a href="#BJC_margins">Page margins</a></li> - <li><a href="#BJC_compile">Makefile and compilation</a></li> - </ul> - </li> - <li><a href="#BJC_usage">Use of the drivers</a></li> - <li> - <ul> - <li><a href="#BJC_options">Supported Options and Defaults</a></li> - <li><a href="#BJC_device_info">Device information</a></li> - <li><a href="#BJC_HW_margins">Hardware margins</a></li> - <li><a href="#BJC_PPD">PostScript printer description (PPD) files</a></li> - <li><a href="#BJC_PPD_custom">Customizing the PPD files</a></li> - </ul> - </li> - - <li><a href="#BJC_bugs">How to report problems</a></li> - <li><a href="#BJC_acks">Acknowledgements</a></li> - </ul> - </li> - - <li><a href="#STC_epson_stylus">Epson Stylus color printer (see also <code>uniprint</code>)</a></li> - <li> - <ul> - <li><a href="#STC_usage">Usage</a></li> - <li><a href="#STC_options">Options</a></li> - <li><a href="#STC_FAQ">Application note and FAQ</a></li> - <li> - <ul> - <li><a href="#STC_FAQ_A3">Support for A3 paper</a></li> - <li><a href="#STC_FAQ_margins">Margins, PageSize</a></li> - <li><a href="#STC_FAQ_II_IIS_1500">Stylus Color II / IIs and 1500</a></li> - </ul> - </li> - <li><a href="#STC_recommendations">Recommendations</a></li> - <li> - <ul> - <li><a href="#STC_dither_experiment">Color dithering experiments with <code>gdevstc</code> 1.21</a></li> - </ul> - </li> - <li><a href="#STC_color_transform">Color transformation</a></li> - <li><a href="#STC_CAM"><code>ColorAdjustMatrix</code></a></li> - <li><a href="#STC_RGBCMYK_coding">RGB / CMYK coding and transfer, and <code>BitsPerPixel</code></a></li> - <li><a href="#What_is_weaving">What is weaving?</a></li> - <li><a href="#STC_print_modes">Print mode parameters</a></li> - <li> - <ul> - <li><a href="#STC_unidirectional"><code>Unidirectional</code></a></li> - <li><a href="#STC_noweave"><code>Microweave</code>, <code>noWeave</code> and <code>OutputCode=deltarow</code></a></li> - <li><a href="#STC_model"><code>Model</code></a></li> - </ul> - </li> - <li><a href="#STC_Pitfalls">Bugs and pitfalls</a></li> - <li><a href="#STC_Tests">Tests</a></li> - <li> - <ul> - <li><a href="#STC_OutputCodes">The various OutputCodes</a></li> - <li><a href="#STC_printing_time">Printing time related to other options</a></li> - </ul> - </li> - <li><a href="#STC_acks">Acknowledgments</a></li> - </ul> - </li> - <li><a href="#Uniprint">uniprint, a flexible unified printer driver</a></li> - <li> - <ul> - <li><a href="#Uni_state">The state of this driver</a></li> - <li><a href="#Uni_background">Notes on <code>uniprint</code>'s background</a></li> - <li><a href="#Uni_make_pfile">Godzilla's guide to the creation of Unified Printer Parameter (<code>.upp</code>) files</a></li> - <li><a href="#Uni_all_parameters">All parameters in brief</a></li> - <li><a href="#Uni_honors"><code>Uniprint</code>'s Roll of Honor</a></li> - <li><a href="#Uni_weaving_howto"><code>Uniprint</code> weaving parameters howto</a></li> - <li><a href="#Uni_esc300">Extension to <code>uniprint</code> for the Epson Stylus Color 300</a></li> - </ul> - </li> -</ul> - - - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p><strong>These devices are no longer supported and/or superceeded by newer methods. -The documentation is kept here for reference. Be advised that these devices -will be removed in future versions of Ghostscript.</strong></p> - -<p>Supported devices are descripted in <a href="Devices">Details of Ghostscript -output devices</a>.</p> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. You may also be interested in <a href="Make.htm">how to -build Ghostscript</a> and <a href="Install.htm">install it</a>, as well as -the description of the <a href="Drivers.htm">driver interface</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Options"></a>Deprecated options</h2> - -<p> -For compatibility with older versions of Ghostscript, <tt>-sOUTPUTFILE</tt> -is a synonym for <tt>-sOutputFile</tt>. It should not be used in new code.</p> - -<hr> - -<h2><a name="HP8_color_inkjet"></a>H-P 8xx, 1100, and 1600 color inkjet printers</h2> - -<p> -This section, written by Uli Wortmann <<a -href="mailto:uliw@erdw.ethz.ch">uliw@erdw.ethz.ch</a>>, deals with the -DeskJet 670, 690, 850, 855, 870, 890, 1100, and 1600.</p> - -<h3><a name="HP8_gdevcd8"></a>Drivers contained in <code>gdevcd8.c</code></h3> - -<p> -The source module <code>gdevcd8.c</code> contains four generic drivers:</p> - -<blockquote> -<table> -<tr> - <td><code>cdj670</code></td> - <td colspan="2">HP DeskJet 670 and 690</td> -</tr> -<tr> - <td><code>cdj850</code></td> - <td colspan="2">HP DeskJet 850, 855, 870, and 1100</td> -</tr> -<tr> - <td><code>cdj890</code></td> - <td colspan="2">HP DeskJet 890</td> -</tr> -<tr> - <td><code>cdj1600</code></td> - <td colspan="2">HP DeskJet 1600</td> -</tr> -</table> -</blockquote> - -<h3><a name="HP8_further_documentation"></a>Further documentation</h3> -<p> <strong>Credits:</strong> Much of the driver is based on ideas derived from the - cdj550 driver of George Cameron. The support for the hp670, hp690, hp890 - and hp1600 was added by Martin Gerbershagen.</p> -<blockquote> - <table> - <tr> - <th width="20%">Date</th> - <th width="20%">Version</th> - <th width="60%">Comments</th> -</tr> - -<tr> - <td>11.11.96</td> - <td>Version 1.0</td> - <td></td> -</tr> -<tr> - <td>25.08.97</td> - <td>Version 1.2</td> - <td>Resolved all but one of the known bugs, introduced a couple of perfomance improvements. Complete new color-transfer-function handling (see gamma).</td> -</tr> -<tr> - <td>01.06.98</td> - <td>Version 1.3</td> - <td>Due to the most welcome contribution of Martin Gerbershagen - (ger@ulm.temic.de), support for the hp670, hp690 and hp890 and - hp1600 has been added. Martin has also resolved all known bugs.<br> - Problems:Dark colors are still pale.</td> -</tr> -</table> -</blockquote> - -<p> -The hp690 is supported through the hp670 device, the hp855, hp870 and the -hp1100 through the hp850 device. The driver needs no longer special -switches to be invoked except <code>-sDEVICE=cdj850</code>, -<code>-sDEVICE=CDJ890</code>, <code>-sDEVICE=CDJ670</code>, or -<code>-sDevice=CDJ1600</code>. The following switches are supported.</p> - -<blockquote> -<table> -<tr> - <td><code>-dPapertype=</code></td> - - <td>0</td> - - <td>plain paper [default]</td> -</tr> -<tr> - <td></td> - - <td>1</td> - - <td>bond paper</td> -</tr> -<tr> - <td></td> - - <td>2</td> - - <td>special paper</td> -</tr> -<tr> - <td></td> - - <td>3</td> - - <td>glossy film</td> -</tr> -<tr> - <td></td> - - <td>4</td> - - <td>transparency film</td> -</tr> -<tr> - <td></td> - <td> </td> - <td>Currently the lookup tables are unsuited for printing on - special paper or transparencies. For these please revert to the - gamma functions.</td> -</tr> -<tr> - <td><code>-dQuality=</code></td> - - <td>-1</td> - - <td>draft</td> -</tr> -<tr> - <td></td> - <td>0</td> - - <td>normal [default]</td> -</tr> -<tr> - <td></td> - <td>1</td> - - <td>presentation</td> -</tr> -<tr> - <td><code>-dRetStatus=</code></td> - - <td>0</td> - - <td>C-RET off</td> -</tr> -<tr> - <td></td> - - <td>1</td> - - <td>C-RET on [default]</td> -</tr> -<tr> - <td><code>-dMasterGamma=</code></td> - - <td>3.0</td> - - <td>[default = 1.0]</td> -</tr> -</table> -</blockquote> - -<blockquote> -<b>Note:</b> To take advantage of the calibrated color-transfer functions, -be sure not to have any gamma statements left! If you need to (i.e., for -overhead transparencies), you still can use the gamma functions, but they -will override the built-in calibration. To use gamma in the traditional -way, set MasterGamma to any value greater than 1.0 and less than 10.0. To -adjust individual gamma values, you have to additionally set MasterGamma to -a value greater than 1.0 and less than 10.0. With the next release, gamma -functions will be dropped. -</blockquote> - -<p> -When using the driver, be aware that printing at 600dpi involves -processing large amounts of data (> 188MB !). Therefore the -driver is not what you would expect to be a fast driver ;-) -This is no problem when printing a full-sized color page (because -printing itself is slow), but it's really annoying if you print only -text pages. Maybe I can optimize the code for text-only pages in a -later release. Right now, it is recommended to use the highest -possible optimisation level your compiler offers. -For the time being, use the cdj550 device with <code>-sBitsPerPixel=3</code> -for fast proof prints. If you simply want to print 600dpi BW data, -use the cdj550 device with <code>-sBitsPerPixel=8</code> (or 1).</p> - -<p> -Since the printer itself is slow, it may help to set the process priority -of the gs process to "regular" or even less. On a 486/100MHz this is still -sufficient to maintain a continuous data flow. Note to OS/2 users: simply -put the gs window into the background or minimize it. Also make sure that -<code>print01.sys</code> is invoked without the <code>/irq</code> -switch (great speed improvement under Warp4).</p> - -<p> -The printer default settings compensate for dot-gain by a calibrated -color-transfer function. If this appears to be too light for your business -graphs, or for overhead transparencies, feel free to set -<code>-dMasterGamma=1.7</code>. Furthermore, you may tweak the gamma -values independently by setting <code>-dGammaValC</code>, -<code>-dGammaValM</code>, <code>-dGammaValY</code> or -<code>-dGammaValK</code> (if not set, the values default to -<code>MasterGamma</code>). This will only work when -<code>-dMasterGamma</code> is set to a value greater than 1.0.</p> - -<p> -Further information, bugs, tips etc, can be found at my website. To learn -more about gamma, see -<a href="ftp://ftp.igd.fhg.de/pub/doc/colour/GammaFAQ.pdf">ftp://ftp.igd.fhg.de/pub/doc/colour/GammaFAQ.pdf</a>.</p> - -<p> -Depending on how you transfer the files, under UNIX you may need to remove -the CRs of the CR-LF sequence used for end-of-line on DOS-based (MS -Windows-based) systems. You can do this in unpacking the files with <code>unzip -a hp850.zip</code>.</p> - -<p> -To compile with gs5.x or later, simply add to your makefile</p> -<blockquote> -DEVICE_DEVS4=cdj850.dev cdj670.dev cdj890.dev cdj1600.dev -</blockquote> - -<p> -Have fun!</p> - -<p> -Uli <<a href="mailto:uliw@erdw.ethz.ch">uliw@erdw.ethz.ch</a>> -<br><a href="http://www.erdw.ethz.ch/~bonk/">http://www.erdw.ethz.ch/~bonk/</a></p> - -<hr> - -<h2><a name="HP880_color_inkjet"></a>H-P 812, 815, 832, 880, 882, 895, and 970 color inkjet printers</h2> - -<p> -This section, written by Matthew Gelhaus <<a -href="mailto:hp880@gelhaus.net">hp880@gelhaus.net</a>>, deals with the -DeskJet 812, 815, 832, 880, 882, 895, and 970.</p> - -<p> -This is a modified version of the <a href="#HP8_color_inkjet">HP8xx driver</a> -written by Uli Wortmann. More information and download are available at -<a href="http://www.gelhaus.net/hp880c/">http://www.gelhaus.net/hp880c/</a>.</p> - -<h3><a name="HP880_gdevcd8"></a>Drivers contained in <code>gdevcd8.c</code></h3> - -<p> -The source module <code>gdevcd8.c</code> contains one generic driver:</p> - -<blockquote> -<table> -<tr> - <td><code>cdj880</code></td> - <td>HP DeskJet 812, 815, 832, 880, 882, 895, and 970</td> -</tr> -</table> -</blockquote> - -<h3><a name="HP880_further_documentation"></a>Further documentation</h3> - -<p> -<b>Credits:</b> This driver is based on the cdj850 driver by Uli Wortmann, and shares the same -internal structure, although the PCL3+ interpretation has changed.</p> - -<blockquote> -<table> - <tr> - <th width="20%">Date</th> - <th width="20%">Version</th> - <th width="60%">Comments</th> -</tr> - -<tr> - <td>15.03.99</td> - - <td>Version 1.3</td> - - <td>Initial version, based on Version 1.3 of Uli Wortmann's driver.</td> -</tr> -<tr> - <td>26.02.00</td> - - <td>Version 1.4beta</td> - - <td>Greatly improved color handling & dithering, but not yet complete enough - to use for text.</td> -</tr> -</table> -</blockquote> - -<p> -All printers are supported through the cdj880 device. Invoke with -<code>-sDEVICE=cdj880</code>. The following switches are supported.</p> - -<blockquote> -<table> -<tr> - <td><code>-dPapertype=</code></td> - - <td>0</td> - - <td>plain paper [default]</td> -</tr> -<tr> - <td></td> - <td>1</td> - - <td>bond paper</td> -</tr> -<tr> - <td></td> - - <td>2</td> - - <td>special paper</td> -</tr> -<tr> - <td></td> - - <td>3</td> - - <td>glossy film</td> -</tr> -<tr> - <td></td> - - <td>4</td> - - <td>transparency film</td> -</tr> -<tr> - <td></td> - <td> </td> - <td>Currently the lookup tables are unsuited for printing on - special paper or transparencies. For these please revert to the - gamma functions.</td> -</tr> -<tr> - <td><code>-dQuality=</code></td> - - <td>-1</td> - - <td>draft</td> -</tr> -<tr> - <td></td> - - <td>0</td> - - <td>normal [default]</td> -</tr> -<tr> - <td></td> - - <td>1</td> - - <td>presentation</td> -</tr> -<tr> - <td><code>-dMasterGamma=</code></td> - - <td>3.0</td> - - <td>[default = 1.0]</td> -</tr> -</table> -</blockquote> - -<p> -The printer default settings compensate for dot-gain by a pre-defined -color-transfer function. If this appears to be too light for your business -graphs, or for overhead transparencies, feel free to set -<code>-dMasterGamma=1.7</code>. Furthermore, you may tweak the gamma -values independently by setting <code>-dGammaValC</code>, -<code>-dGammaValM</code>, <code>-dGammaValY</code> or -<code>-dGammaValK</code> (if not set, the values default to -<code>MasterGamma</code>). This will only work when -<code>-dMasterGamma</code> is set to a value greater than 1.0.</p> - -<p> -Further information, bugs, tips etc, can be found at my website.</p> - -<p> -To compile with gs6.x or later, simply add to your makefile</p> -<blockquote> -DEVICE_DEVS4=$(DD)cdj880.dev -</blockquote> - -<p> -Matthew Gelhaus <<a href="mailto:hp880@gelhaus.net">mailto:hp880@gelhaus.net</a>> -<br><a href="http://www.gelhaus.net/hp880c/">http://www.gelhaus.net/hp880c/</a></p> - -<hr> - -<h2><a name="HP_color_inkjet"></a>H-P color inkjet printers</h2> - -<p> -This section, written by George Cameron, deals with the DeskJet 500C, -DeskJet 550C, PaintJet, PaintJet XL, PaintJet XL300, the DEC LJ250 -operating in PaintJet-compatible mode.</p> - -<h3><a name="HP_gdevcdj"></a>Drivers contained in <code>gdevcdj.c</code></h3> - -<p> -The source module <code>gdevcdj.c</code> contains six generic drivers:</p> - -<blockquote> -<table> -<tr> - <td><code>cdj500</code></td> - <td>HP DeskJet 500C and 540C</td> -</tr> -<tr> - <td><code>cdj550</code></td> - <td>HP DeskJet 550C, 560C, 660C, 660Cse</td> -</tr> -<tr> - <td><code>pjxl300</code></td> - <td>HP PaintJet XL300, DeskJet 1200C, and CopyJet</td> -</tr> -<tr> - <td><code>pjtest</code></td> - <td>HP PaintJet</td> -</tr> -<tr> - <td><code>pjxltest</code></td> - <td>HP PaintJet XL</td> -</tr> -<tr> - <td><code>declj250</code></td> - <td>DEC LJ250</td> -</tr> -</table> -</blockquote> - -<p> -All these drivers have 8-bit (monochrome), 16-bit and 24-bit (colour) and -for the DJ 550C, 32-bit (colour, CMYK mode) options in addition to standard -colour and mono drivers. It is also possible to set various -printer-specific parameters from the command line, for example</p> - -<blockquote><code> -gs -sDEVICE=cDeskJet -dBitsPerPixel=16 -dDepletion=1 -dShingling=2 tiger.eps -</code></blockquote> - -<p> -<b>Note:</b> the old names <code>cDeskJet</code>, -<code>cdjcolor</code> and <code>cdjmono</code> drivers have been -retained; however, their functionality duplicates that available using the -drivers above (and <code>cDeskJet</code> is identical to -<code>cdj500</code>). That is, we can use</p> - -<blockquote> -<table> -<tr> - <td><code>gs -sDEVICE=cdj500 -dBitsPerPixel=24</code></td> - <td>for <code>cdjcolor</code>, and</td> -</tr> -<tr> - <td><code>gs -sDEVICE=cdj500 -dBitsPerPixel=1</code></td> - <td>for <code>cdjmono</code></td> -</tr> -</table> -</blockquote> - -<h3><a name="HP_paper_size"></a>Default paper size</h3> - -<p> -If the preprocessor symbol <code>A4</code> is defined, the default paper -size is ISO A4; otherwise it is U.S. letter size (see about -<a href="Use.htm#Known_paper_sizes">paper sizes</a> in the usage -documentation). You can <a href="Use.htm#Paper_size">specify other paper -sizes</a> on the command line, including A3 for the PaintJet XL and -PaintJet XL300, as also explained in the usage documentation.</p> - -<h3><a name="HP_limits"></a>DeskJet physical limits</h3> - -<p> -The DeskJet's maximum printing width is 2400 dots, or 8 inches -(20.32cm). The printer manuals say that the maximum recommended printing -height on the page is 10.3 inches (26.16cm), but since this is obviously -not true for A4 paper, and I have been unable to detect any problems in -printing longer page lengths, this would seem to be a rather artificial -restriction.</p> - -<p> -All DeskJets have 0.5 inches (1.27cm) of unprintable bottom margin, due to the mechanical -arrangement used to grab the paper. Side margins are approximately 0.25 inches (0.64cm) -for U.S. letter paper, and 0.15 inches (0.38cm) for A4.</p> - -<h4><a name="HP_command_line"></a>Printer properties (command-line parameters)</h4> - -<p> -Several printer "properties" have been implemented for these printers. -Those available so far are all integer quantities, and thus may be -specified, for instance, like</p> - -<blockquote> -<code>gs -dBitsPerPixel=32 -dShingling=1</code> ... -</blockquote> - -<p> -which sets the <code>BitsPerPixel</code> parameter to 32 and the -<code>Shingling</code> parameter to 1.</p> - -<h4><a name="HP_bpp"></a>Bits per pixel</h4> - -<p> -If the preprocessor symbol <code>BITSPERPIXEL</code> is defined as an -integer (see below for the range of allowable values), that number defines -the default bits per pixel (bit depth) for the generic drivers. If the -symbol is undefined, the default is 24 bits per pixel. It is, of course, -still possible to specify the value from the command line as described -below. Note also that the <code>cDeskJet</code>, -<code>cdjcolor</code> and <code>cdjmono</code> drivers are unaffected -by setting this symbol, as their default settings are predefined to be 1, 3 -and 24 respectively.</p> - -<p> -All of the drivers in <code>gdevcdj.c</code> accept a command line -option to set the <code>BitsPerPixel</code> property. This gives -considerable flexibility in choosing various tradeoffs among speed, -quality, colour, etc. The valid numbers are:</p> - -<blockquote> -<table> - <tr> - <th width="15%">BITSPERPIXEL</th> - <th width="85%">Comments</th> - </tr> -<tr> - <td><strong>1</strong></td> - <td>A standard Ghostscript monochrome driver, using black ink (by - installing the separate mono cartridge in the case of the DeskJet 500C, or - automatically for the other printers).</td> -</tr> -<tr> - <td><b>3</b></td> - <td>A standard Ghostscript colour driver, using internal dithering. This - is fast to compute and to print, but the clustered dithering can lose some - detail and colour fidelity.</td> -</tr> -<tr> - <td><b>8</b></td> - <td>An "error-diffusion" monochrome driver which uses Floyd-Steinberg - dithering to print greyscale images. The patterns are much more randomised - than with the normal clustered dithering, but the data files can be much - larger and somewhat slower to print.</td> -</tr> -<tr> - <td><b>16</b></td> - <td>A "cheaper" version of the 24-bit driver, which generates - Floyd-Steinberg colour dithered output using the minimum memory (this may - be helpful when using Ghostscript has not been compiled using a 16-bit - build environment). The quality can be almost as good as the 24-bit - version.</td> -</tr> -<tr> - <td><b>24</b></td> - <td>A high-quality colour driver using Floyd-Steinberg dithering for - maximum detail and colour range. However, it is very memory-intensive, and - thus can be slow to compute. It tends to produce rather larger raw data - files, so they can also take longer to print.</td> -</tr> -<tr> - <td><b>32</b></td> - <td>Only for the DeskJet 550C, which uses the black cartridge and the - colour cartridge simultaneously (that is, CMYK printing). This printer can - both be faster and give higher quality than the DeskJet 500C, because of - the true black ink. (Note that the 24-bit mode also permits CMYK printing - on this printer, and uses less memory). Any differences between 24-bit and - 32-bit should be small.</td> -</tr> -</table> -</blockquote> - -<h4><a name="HP_DeskJet_properties"></a>DeskJet properties</h4> - -<blockquote> -<table> -<tr> - <th width="20%">Name</th> - <th width="20%">Type</th> - <th width="60%">Comments</th> -</tr> -<tr> - <td><code>BlackCorrect</code></td> - - <td><code>int</code></td> - - <td>Colour correction to give better blacks when using the DJ500C in colour mode. For example, the default of 4 reduces the cyan component to 4/5. Range accepted: 0 - 9 (0 = none).</td> -</tr> -<tr> - <td><code>Shingling</code></td> - - <td><code>int</code></td> - - <td>Interlaced, multi-pass printing: 0 = none, 1 = 50%, 2 = 25%, 2 is best and slowest.</td> -</tr> -<tr> - <td><code>Depletion</code></td> - - <td><code>int</code></td> - - <td>"Intelligent" dot-removal: 0 = none, 1 = 25%, 2 = 50%, 1 best for graphics? Use 0 for transparencies.</td> -</tr> -</table> -</blockquote> - -<h4><a name="HP_PaintJet_properties"></a>PaintJet XL300 / PaintJet XL properties</h4> - -<blockquote> -<table> -<tr> - <th width="20%">Name</th> - <th width="20%">Type</th> - <th width="60%">Comments</th> -</tr> -<tr> - <td><code>PrintQuality</code></td> - - <td><code>int</code></td> - - <td>Mechanical print quality: -1 = fast, 0 = normal, 1 = presentation. Fast mode reduces ink usage and uses single-pass operation for some media types. Presentation uses more ink and the maximum number of passes, giving slowest printing for highest quality</td> -</tr> -<tr> - <td><code>RenderType</code></td> - - <td><code>int</code></td> - - <td><dl> - <dt><dd><code>0 </code>driver does dithering</dd></dt> - <dt><dd><code>1 </code>snap to primaries</dd></dt> - <dt><dd><code>2 </code>snap black to white, others to black</dd></dt> - <dt><dd><code>3 </code>ordered dither</dd></dt> - <dt><dd><code>4 </code>error diffusion</dd></dt> - <dt><dd><code>5 </code>monochrome ordered dither</dd></dt> - <dt><dd><code>6 </code>monochrome error diffusion</dd></dt> - <dt><dd><code>7 </code>cluster ordered dither</dd></dt> - <dt><dd><code>8 </code>monochrome cluster ordered dither</dd></dt> - <dt><dd><code>9 </code>user-defined dither (not supported)</dd></dt> - <dt><dd><code>10 </code>monochrome user-defined dither ns.</dd></dt> - </dl></td> -</tr> -</table> - -<p> -The PaintJet (non-XL) has no additional properties.</p> - -</blockquote> - -<h3><a name="HP_gamma"></a>Gamma correction</h3> - -<p> -One consequence of using Floyd-Steinberg dithering rather than Ghostscript's -default clustered ordered dither is that it is much more obvious that the -ink dots are rather larger on the page than their nominal 1/180-inch or 1/300-inch -size (clustering the dots tends to minimise this effect). Thus it is often -the case that the printed result is rather too dark. A simple empirical -correction for this may be achieved by preceding the actual PostScript -file to be printed by a short file which effectively sets the gamma for -the device, such as</p> - -<blockquote><code> -gs ... gamma.ps colorpic.ps -c quit -</code></blockquote> - -<p> -where <code>gamma.ps</code> is</p> - -<blockquote> -<pre>%! -/.fixtransfer { - currentcolortransfer 4 { - mark exch - dup type dup /arraytype eq exch /packedarraytype eq or - 1 index xcheck and { /exec load } if - 0.333 /exp load - ] cvx 4 1 roll - } repeat setcolortransfer -} bind odef -.fixtransfer -/setpagedevice { setpagedevice .fixtransfer } bind odef</pre> -</blockquote> - -<p> -This does the gamma correction <b><em>after</em></b> whatever correction -the device might be doing already. To do the correction -<b><em>before</em></b> the current correction,</p> - -<blockquote> -<pre>%! -/.fixtransfer { - currentcolortransfer 4 { - mark 0.333 /exp load 4 -1 roll - dup type dup /arraytype eq exch /packedarraytype eq or - 1 index xcheck and { /exec load } if - ] cvx 4 1 roll - } repeat setcolortransfer -} bind odef -.fixtransfer -/setpagedevice { setpagedevice .fixtransfer } bind odef</pre> -</blockquote> - -<p> -This example sets the gamma for R, G, and B to 3, which seems to work -reasonably well in practice.</p> - -<h3><a name="HP_resolution_enhance"></a>HP's resolution-enhanced mode for Inkjet printers</h3> - -<p> -This feature is available on HP's more recent inkjet printers, including -the DeskJet 520 (mono), 540 (mono or colour) and 560C (mono and colour). -The colour and monochrome drivers for the HP DeskJet 550c are (probably) -the best you will get for use with Ghostscript, for the following reasons.</p> - -<p> -These printers do not offer true 600×300dpi resolution. Those that -print in colour are strictly 300×300dpi in colour mode, while in mono -mode there is a pseudo 600×300dpi mode with the restriction that you -can't print two adjacent dots. In effect what you have is 600dpi dot -positioning, but on average you don't get more dots per line. This -provides the possibility, for instance, to have sharper character outlines, -because you can place dots on the edges nearer to their ideal positions. -This is why it is worth doing.</p> - -<p> -However, HP will not support user-level programming of this -resolution-enhanced mode, one reason being that (I understand) all the dot -spacing has to be done by the driver, and if you get it wrong, you can -actually damage the print head.</p> - -<p> -To summarise, you may lose a smidgin of (potential) text clarity using the -550c drivers (<code>cdj550</code>, <code>cdjcolor</code>, -<code>cdjmono</code> etc.), but other than that, they are the ones for -the job.</p> - -<h3><a name="HP_tips"></a>General tips</h3> - -<p> -For all the printers above, the choice of paper is critically important to -the final results. The printer manuals suggest type of paper, but in -general, smoother, less fibrous types give better results. In particular, -the special ink-jet paper can make a big difference: colours are brighter, -but most importantly, there is almost no colour bleed, even with adjacent -areas of very heavy inking. Similarly the special coated transparencies -also work well (and ordinary transparencies do not work at all!).</p> - -<p> -The Unix procedure <a href="Unix-lpr.htm"><code>unix-lpr.sh</code></a> -provides one example of setting up a multi-option colour PostScript -<code>lpr</code> queue on Unix systems, and includes the ability to -choose a range of different colour options and printer accounting and error -logging.</p> - -<p> -<b>Caveat emptor!</b> It is not always easy for me to test all of these -drivers, as the only colour printer I have here is the DeskJet 500C. I rely -on others to test drivers for the additional machines and report their -findings back to me.</p> - -<hr> - -<h2><a name="BJC_8200"></a>Canon BJC-8200 printer</h2> - -<p> -This section was contributed by the author of the <code>uniprint</code> -configuration files for the Canon BJC-8200, Stephan C. Buchert <<a -href="mailto:scb@stelab.nagoya-u.ac.jp">scb@stelab.nagoya-u.ac.jp</a>>. -These files also handle the Japanese Canon F850 printer.</p> -<p> -Warning: Usage of this program is neither supported nor endorsed by -the Canon corporation. Please see the Ghostscript <a -href="Public.htm">license</a> regarding warranty.</p> - -<h3>Introduction</h3> - -<p> -The Canon Bubble Jet printer BJC-8200 is designed for printing digital -photos and halftone images. Software drivers for Windows 95-2000 and Mac are -usually included and can be downloaded from the Canon web sites like -<a href="http://consumer.usa.canon.com/bjc/bjc8200/">http://consumer.usa.canon.com/bjc/bjc8200/</a> -for the US market. If these drivers cannot be used for some reason, then at -present Ghostscript is probably the alternative giving the best results.</p> - -<p> -The BJC-8200 has features not found among the specs of earlier bubble jet -models (except the even more advanced BJC-8500) and is advertised to offer:</p> - -<ol> - -<li>microfine droplet technology;</li> - -<li>support for printing on a new type of paper, Photo Paper Pro;</li> - -<li>a printhead capable of printing up to 1200 DpI;</li> - -<li>individual ink tanks for 6 colors;</li> - -<li>an internal status monitor reporting low ink back to a driver;</li> - -<li>an optional color scanner cartridge for up to 600 DpI resolution.</li> - -</ol> - -<p> -Access to features 5 and 6 requires use of the original Canon drivers for -the foreseeable future. This README is about getting the printer features -1-3 working with Ghostscript. No (re)compilation of Ghostscript is normally -required.</p> - -<p> -Ghostscript comes with a relatively highly configurable driver, called -<a href="#Uniprint">uniprint</a>, for printers which understand raster -images in various propriety formats. Most options for this driver are -usually organized into files having the suffix ".upp." Ghostscript -versions >= 5.10 (or even earlier) include such uniprint control files -for the Canon BJC-610. They work also well for some other Canon Bubble -Jet models, for example for my BJC-35vII. But when using them for a -BJC-8200 the result is unsatisfactory.</p> - -<h3>The uniprint control files for the BJC-8200</h3> - -<p> -After some experimenting with the options for uniprint I have obtained quite -satisfactory prints with my printer(*). This distribution includes six new -uniprint control files:</p> - -<ul> -<li>bj8pp12f.upp</li> -<li>bj8hg12f.upp</li> -<li>bj8gc12f.upp</li> -<li>bj8oh06n.upp</li> -<li>bj8ts06n.upp</li> -<li>bj8pa06n.upp</li> -</ul> - -<p> -They are included in Ghostscript >=6.21. For older versions you can put -them anywhere in the Ghostscript search path (type "gs -h" to see the -path), but should perhaps add the files to the directory with the -other *.upp files. This is "/usr/share/ghostscript/gs6.01/lib" in my -RedHat 6.1 Linux box with Aladdin Ghostscript 6.01. - -<p> -Here is an explanation of my file name convention: the prefix "bj8" should -perhaps be used for the Canon BJC-8200 and compatible (like the Japanese -F850 and perhaps the non-Japanese BJC-8500) models. The next two letters -indicate the print media:</p> - -<ul> -<li>pp "Photo Paper Pro"</li> -<li>hg "High Gloss Photo Film"</li> -<li>gc "Glossy Photo Cards"</li> -<li>oh "OHP transparencies"</li> -<li>ts "T-shirt transfer"</li> -<li>pa "Plain Paper"</li> -</ul> - -<p> -The numbers at positions 6 and 7 indicate the resolution</p> - -<ul> -<li>12 1200x1200 DpIxDpI</li> -<li>06 600x600 DpIxDpI</li> -</ul> - -<p> -The last letter stands for a quality factor that effects also the print -speed (presumably related to the number of passes that the printhead makes). -</p> -<ul> -<li>f highest quality</li> -<li>n normal quality</li> -</ul> - -<p> -Printing a postcard size (~10x15 cm^2) image at 1200x1200 DpI^2 takes about -3 minutes. The output of Ghostscript is then typically 4-5 MByte. The -bootleneck seems to be the transfer of the raster image in run-length -encoded Canon format to the printer (via the parallel port on my system) or -the printer's speed, not Ghostscript or the uniprint renderer.</p> - -<h3>Further Optimization for the Canon BJC-8200</h3> - -<p>So far I have only experimented with the printer initialization code at the -beginning of each page (-dupBeginPageCommand) and the resolution (-r). Other -options, particularly the transfer arrays (-dupBlackTransfer, --dupCyanTransfer, -dupMagentaTransfer, -dupYellowTransfer) and the margins -(-dupMargins) were simply copied from the files for the BJC-610, but they -may need to be changed for optimized performance.</p> - -<p> -Here is information useful for changing or adding uniprint control files for -the BJC-8200:</p> - -<p> -In "-dupBeginPageCommand=..." use the line</p> - -<blockquote> - 1b28 64 0400 04b0 04b0 -</blockquote> - -<p> -for 1200x1200 resolution, and</p> - -<blockquote> - 1b28 64 0400 0258 0258 -</blockquote> - -<p> -for 600x600. The "-r" option in the control file must of course match this -line. Other resolutions might work as well, but I didn't try.</p> - -<p> -Crucial are the numbers in the lines like</p> - -<blockquote><pre> - 1b28 63 0300 3005 04 - ^ ^ - Plain Paper 0 4 Highest quality - OHP transparency 2 . - T-shirt transfer 3 . - Glossy Photo Film 5 . - High Gloss Paper 6 0 Lowest quality - Photo Paper Pro 9 -</pre></blockquote> - -<h3>Outlook</h3> - -<p> -Presently uniprint can use the black (K), cyan (C), magenta (M), and -yellow (Y) colors in the BJC-8200. The unused colors are photo (or -light) cyan (c) and magenta (m). Also the Canon driver seems to use -only CMYK, for example when printing on Photo Paper Pro in "Camera" or -"SuperPhoto" mode. These modes supposedly produce prints of the best -quality that the Canon driver can offer. Other modes of Canon driver -do use up to all six color cartridges (CMYKcm). Therefore expanding -uniprint's capabilities for six colors would be interesting, but it may -not increase the output quality of 6-color printers such as the -BJC-8200 drastically.</p> - -<p> -More control files for uniprint could be added in order to offer more -versatility for controlling the BJC-8200 within a Ghostscript -installation. The number of possible combinations for media type, resolution -and print quality factor is very large, many combinations would not make -much sense, many might be used here and there, but relatively rarely. The -user would have to remember a name for each combination that is used.</p> - -<p> -A better way would be to let the user patch optionally a user owned or -system wide uniprint control file before each print via some print -tool. This is similar to the approach taken by Canon with their driver for -Windows. Similarly a uniprint tool could also incorporate other functions -such as printing test and demo pages and the low ink warning once the -protocol for this is known. Clearly it would be difficult to code such a -uniprint tool for all the platforms where Ghostscript is running.</p> - -<h3>Usage on RedHat Linux</h3> - -<p> -In order to install a BJC-8200 printer on a RedHat Linux system with -RedHat's printtool, you need also to insert with a text editor the contents -of the file <code>bj8.rpd</code> into the RedHat printer database -<code>/usr/lib/rhs/rhs-printfilters/printerdb</code>. Insert it most -appropriately after the section</p> - -<blockquote><pre> -StartEntry: U_CanonBJC610 -. -. -. -EndEntry - -< --- insert here "bj8.rpd" from this distribution: -< --- StartEntry: U_CanonBJC8200 - . - . - . -</pre></blockquote> - -<h3>Contacting the Author</h3> - -<p> -E-mail address: <<a -href="mailto:scb@stelab.nagoya-u.ac.jp">scb@stelab.nagoya-u.ac.jp</a>></p> - -<p> -Footnotes:</p> - -<p> -(*) Actually I have a F850, not a BJC-8200. That model is sold for the -Japanese market only. The specs and also the external look are the -same as those of the BJC-8200 models for the American and European -markets. I expect that the raster image mode which is used exclusively -by Ghostscript is entirely compatible for both models.</p> - -<p> -Stephan C. Buchert</p> - -<hr> - -<h2><a name="BJC"></a>Other Canon BubbleJet (BJC) printers</h2> - -<p> -This section was contributed by the author of the drivers, Yves Arrouye -(<<a href="mailto:yves.arrouye@usa.net">yves.arrouye@usa.net</a>>, but -please do not send questions to him: he no longer maintains these drivers.) -The drivers handle Canon BJC-600, BJC-4xxx, BJC-70, Stylewriter 2x00, and -BJC-800 printers.</p> - -<h3><a name="BJC_history"></a>History</h3> - -<p> -The BJC-600 driver was written in the first place by Yoshio Kuniyoshi and -later modified by Yves Arrouye. We tried to make it evolve synchronously, -though Yoshio cannot be reached since a long time ago. The drivers are -based on code for the HP printers by George Cameron (in fact, they are in -the same file!), so he's the first person to thank.</p> - -<p> -The 2.00 version of the drivers was a complete rewrite of the driver -(arguments, optimization, colour handling, in short: everything!) by Yves -Arrouye. That release was also the first one to be able to use the full -width of an A3 paper size. PostScript Printer Description (PPD) files for -the drivers were released with version 2.15. They are incomplete, -but they can be used to drive the printers' main features.</p> - -<h3><a name="BJC_build"></a>Configuring and building the BJC drivers</h3> - -<h4><a name="BJC_defaults"></a>Modify values in -<code>gdevbjc.h</code></h4> - -<p> -Configure the drivers by modifying the default values in the file -<code>gdevbjc.h</code> or on the compilation line. If you don't do -that, the drivers use reasonable defaults that make them work "as -expected". All default values shown here are defined in that file.</p> - -<h4><a name="BJC_CMYK_RGB"></a>CMYK-to-RGB color conversion</h4> - -<p> -By default, the drivers use the same algorithm as Ghostscript to convert -CMYK colors to RGB. If you prefer to use Adobe formulas, define -<code>USE_ADOBE_CMYK_RGB</code> when compiling. (See the top of the -file <code>gdevcdj.c</code> to see the difference between the two.)</p> - -<h4><a name="BJC_vertical_centering"></a>Vertical centering of the -printable area</h4> - -<p> -The drivers center the imageable area horizontally but not vertically, so -that what can be printed does use the most of the output media. If you -define <code>BJC_DEFAULT_CENTEREDAREA</code> when compiling, then the -top and bottom margins will be the same, resulting in a (smaller) -vertically centered imageable area also.</p> - -<h4><a name="BJC_margins"></a>Page margins</h4> - -<p> -If you define <code>USE_RECOMMENDED_MARGINS</code>, then the top and -bottom margins will be the same (that is, -<code>BJC_DEFAULT_CENTEREDAREA</code> will be defined for you) and the -margins will be the 12.4mm recommended by Canon. Since margins are -complicated (because one must rely on the mechanical precision of the -printer), the drivers do something about the bottom margin: by default the -bottom margin is 9.54mm for the BJC-600 driver and 7mm for the BJC-800. If -you define <code>USE_TIGHT_MARGINS</code>, then the bottom margin is 7mm -for both drivers (but I never managed to get my own BJC-600 to print a line -on this low bound, hence the larger default). Regardless of the presence -of this definition, <code>USE_FIXED_MARGINS</code> will not allow the -BJC-800 to use the lower 7mm bottom margin, so if you have a problem with -the bottom margin on a BJC-800, just define that (without defining -<code>USE_TIGHT_MARGINS</code>, of course).</p> - -<p> -A quick way to be sure the margins you selected is to print a file whose -contents are:</p> - -<blockquote><code> -%!<br> -clippath stroke showpage -</code></blockquote> - -<p> -If the margins are okay, you will get a rectangle visibly surrounding -the printable area. If they're not correct, one or more of the sides will -be either incomplete or completely unprinted.</p> - -<h4><a name="BJC_compile"></a>Makefile and compilation</h4> - -<p> -Make sure the <code>bjc600</code> or <code>bjc800</code> devices are -in <a href="Make.htm#Features_and_devices"><code>DEVICE_DEVS</code> in -the makefile</a>; that is, look in the makefile for your platform and add -them if necessary -- they may already be there. As of Ghostscript 5.10, -for instance, one makefile has</p> - -<blockquote><code> -DEVICE_DEVS6=bj10e.dev bj200.dev bjc600.dev bjc800.dev -</code></blockquote> - -<h3><a name="BJC_usage"></a>Use of the drivers</h3> - -<p> -There are two drivers here. The "<code>bjc600</code>" one supports the BJC-600 and -BJC-4xxx (maybe the BJC-70 as well) and the "<code>bjc800</code>" one supports the -BJC-800 series. Remarks here that apply to both drivers use the name -"bjc".</p> - -<h4><a name="BJC_options"></a>Supported Options and Defaults</h4> - -<p> -Note: "options", "properties", and "parameters" designate the same thing: -device parameters that you can change.</p> - -<p> -Giving an option an incorrect value causes an error. Unless stated -otherwise, this error will be a rangecheckerror. Options may be set from -the Ghostscript command line (using the <code>-d</code> and -<code>-s</code> switches or other predetermined switches if they have an -effect on the driver) or using the PostScript Level 2 -<code>setpagedevice</code> operator if Ghostscript has been compiled -with the <code>level2</code> or <code>level3</code> device (which it should -<code>;-)</code>). There are <b>no</b> special-purpose operators such as -one was able to find in Level 1 printers.</p> - -<p> -The bjc uses 24 bits per pixel by default (unless you change the value of -<code>BJC_BITSPERPIXEL</code>), corresponding to CMYK printing. -Supported modes are 1 bpp and 4 bpp (gray levels), 8 bpp, 16 bpp, 24 bpp -and 32 bpp (colours). Colours are preferably stored in the CMYK model -(which means, for example, that with 16 bpp there are only 16 different -shades of each color) but it is possible to store them as RGB color for -some depths. Some modes do Floyd-Steinberg dithering and some don't, but -use the default Ghostscript halftoning (in fact, when halftoning is used, -dithering takes also place but because of the low point density it is -usually not efficient, and thus invisible).</p> - -<blockquote> - - -<h4>Descriptions of printing modes by bpp and Colors</h4> - - -<table> - -<tr> - <th width="15%">bpp</th> - - <th width="15%">Colors</th> - - <th align="left" width="70%">Mode</th> - </tr> -<tr> - <td>32</td> - - <td align="center">4</td> - - <td>CMYK colour printing, Floyd-Steinberg dithering</td> -</tr> -<tr> - <td>24</td> - - <td align="center">4</td> - - <td>The same. (But each primary colour is stored on 6 bits instead of 8.)</td> -</tr> -<tr> - <td>24</td> - - <td align="center">3</td> - - <td>RGB colour printing, Floyd-Steinberg dithering. This mode does - <code>not</code> use the black cartridge (that's why it - exists, for when you don't want to use it <code>;-)</code>). - Each primary colour is stored in 8 bits as in the 32/4 mode, - but black generation and under-color removal are done on the - driver side and not by Ghostscript, so you have no control over - it. (This mode is no longer supported in this driver.)</td> -</tr> -<tr> - <td>16</td> - - <td align="center">4</td> - - <td>CMYK colour printing, halftoned by Ghostscript. F-S dithering - is still visible here (but the halftone patterns are visible - too!).</td> -</tr> -<tr> - <td>8</td> - - <td align="center">4</td> - - <td>The same.(But each primary colour is stored in 2 bits instead of 4.)</td> -</tr> -<tr> - <td>8</td> - - <td align="center">3</td> - - <td>RGB colour printing. This mode is not intended for use. What I - mean is that it should be used only if you want to use custom - halftone screens <b>and</b> the halftoning is broken using the - 8/4 mode (some versions of Ghostscript have this problem).</td> -</tr> -<tr> - <td>8</td> - - <td align="center">1</td> - - <td>Gray-level printing, Floyd-Steinberg dithering</td> -</tr> -<tr> - <td>1</td> - - <td align="center">1</td> - - <td>Gray-level printing halftoned by Ghostscript</td> - </tr> -</table> -</blockquote> - -<p> -These modes are selected using the <code>BitsPerPixel</code> <b>and</b> -<code>Colors</code> integer options (either from the command line or in -a PostScript program using <code>setpagedevice</code>). See below.</p> - -<p> -A note about darkness of what is printed: Canon printers do print dark, -really. And the Floyd-Steinberg dithering may eventually darken your image -too. So you may need to apply gamma correction by calling Ghostscript as in</p> - -<blockquote><code> -gs -sDEVICE=bjc600 gamma.ps myfile.ps -</code></blockquote> - -<p> -where <code>gamma.ps</code> changes the gamma correction (here to 3 for -all colors); 0.45 gives me good results, but your mileage may vary. The -bigger the value the lighter the output:</p> - -<blockquote><code> -{ 0.45 exp } dup dup currenttransfer setcolortransfer -</code></blockquote> - -<p> -The drivers support printing at 90dpi, 180dpi and 360dpi. Horizontal and -vertical resolutions must be the same or a limitcheck error will happen. A -rangecheck will happen too if the resolution is not -90 ×2^<small><sup><b>N</b></sup></small>. If the driver -is compiled with <code>-DBJC_STRICT</code> a rangecheck also happens if -the resolution is not one of those supported. This is not the case, as we -expect that there may be a 720dpi bjc some day.</p> - -<p> -Here are the various options supported by the bjc drivers, along with -their types, supported values, effects, and usage:</p> - -<dl> - <dt><code>BitsPerPixel</code> (int) - <dd>Choose the depth of the page. Valid values are 1, 8, 16, 24 (the - default) and 32. - -<p> -Note that when this is set for the first time, the <code>Colors</code> -property is automatically adjusted unless it is also specified. The table -here shows the corresponding color models and the rendering method visible: -"GS" for Ghostscript halftoning and "F-S" for Floyd-Steinberg dithering. -When both are present it means that the dithering of halftones is visible. -Default choices are indicated by asterisk "*".</p> - -<blockquote> - <h4>Valid colors values for allowed BitsPerPixel values</h4> -<table> - -<tr> - <th>bpp</th> - <th>Colors</th> - <th>Default</th> - <th>Color model</th> - <th>Dithering</th> -</tr> -<tr> - <td align="center">32</td> - <td align="center">4</td> - <td> </td> - <td>CMYK</td> - <td>F-S</td> -</tr> -<tr> - <td align="center">24</td> - <td align="center">4</td> - <td><b>*</b></td> - <td>CMYK</td> - <td>F-S</td> -</tr> -<tr> - <td> </td> - <td align="center">3</td> - <td> </td> - <td>RGB</td> - <td>F-S</td> -</tr> -<tr> - <td align="center">16</td> - <td align="center">4</td> - <td> </td> - <td>CMYK</td> - <td>GS, F-S</td> - </tr> -<tr> - <td align="center">8</td> - <td align="center">4</td> - <td><b>*</b></td> - <td>CMYK</td> - <td>GS</td> -</tr> -<tr> - <td> </td> - <td align="center">3</td> - <td> </td> - <td>RGB</td> - <td>GS</td> -</tr> -<tr> - <td> </td> - <td align="center">1</td> - <td> </td> - <td>K (CMYK</td> - <td>F-S</td> -</tr> -<tr> - <td align="center">1</td> - <td align="center">1</td> - <td><b>*</b></td> - <td>K (CMYK)</td> - <td>GS</td> -</tr> -</table> -</blockquote> - -<p>Also note that automagical change of one parameter depending on the -other one does not work in a <code>setpagedevice</code> call. This -means that if you want to change <code>BitsPerPixel</code> to a value -whose valid <code>Colors</code> values do not include the actual -<code>Colors</code> value, you must change <code>Colors</code> too.</p> -</dl> - -<dl> -<dt><code>Colors</code> (int) -<dd>Choose the number of color components from among 1, 3 and 4 (the -default). This setting cannot be used in a PostScript program, only on -Ghostscript's command line. See <code>ProcessColorModel</code> below -for what to use to change the number of colors with PostScript code. - -<p> -Note that setting this property does limit the choices of -<code>BitsPerPixel</code>. As for the previous property, its first -setting may induce a setting of the "other value" -(<code>BitsPerPixel</code> here). The table here indicates valid -combinations with "V", default values with asterisk "*".</p> - -<blockquote><table> -<tr> - <th colspan="7">Valid BitsPerPixel values for allowed Colors values</th> -</tr> -<tr> - <td colspan="7" align="right">BitsPerPixel OK values</td> -</tr> -<tr> - <td>Colors</td> - <td>Type</td> - <td>32</td> - <td>24</td> - <td>16</td> - <td>8</td> - <td>1</td> -</tr> -<tr> - <td>4</td> - <td>CMYK</td> - <td><b>V</b></td> - <td><b>*</b></td> - <td><b>V</b></td> - <td><b>V</b></td> - <td></td> -</tr> -<tr> - <td>3</td> - <td>RGB</td> - <td> </td> - <td><b>*</b></td> - <td> </td> - <td><b>V</b></td> - <td> </td> -</tr> -<tr> - <td>1</td> - <td>K</td> - <td> </td> - <td> </td> - <td> </td> - <td><b>V</b></td> - <td><b>*</b></td> -</tr> -</table> -</blockquote> - -<p>Also note that automagical change of one parameter depending on the -other one does not work in a <code>setpagedevice</code> call. This -means that if you want to change <code>Colors</code> to a value whose -valid <code>BitsPerPixel</code> values don't include the actual -<code>BitsPerPixel</code> value, you must change -<code>BitsPerPixel</code> too.</p> -</dl> - -<dl> -<dt><code>ProcessColorModel</code> (symbol)</dt> -<dd>A symbol taken from <code>/DeviceGray</code>, -<code>/DeviceRGB</code> or <code>/DeviceCMYK</code> which can be used -to select 1, 3 or 4 colors respectively. Note that this parameter takes -precedence over <code>Colors</code>, and that both affect the same -variable of the driver. (See <code>Colors</code> above for values -combined with <code>BitsPerPixel</code>.)</dd> -</dl> - -<dl> -<dt><code>HWResolution</code> (floats array)</dt> -<dd>An array of two floats giving the horizontal and vertical resolution in -dots per inch from among 90, 180 and 360 (the default). Both values must -be the same. On the Ghostscript command line, the resolution may be -changed with the <a href="Use.htm#Resolution_switch"><code>-r</code> -switch</a>.</dd> -</dl> - -<dl> -<dt><code>ManualFeed</code> (bool)</dt> -<dd>Indicate that the sheets won't be fed automatically by the printer, -<code>false</code> by default. (Not meaningful on the BJC-600, I fear.)</dd> -</dl> - -<dl> -<dt><code>MediaType</code> (string)</dt> -<dd>The media to print on, chosen from among "<code>PlainPaper</code>", -"<code>CoatedPaper</code>", "<code>TransparencyFilm</code>", -"<code>Envelope</code>", "<code>Card</code>" and -"<code>Other</code>". Default is "<code>PlainPaper</code>". For -"<code>Envelope</code>", "<code>Card</code>" or -"<code>Other</code>" the driver puts the printer into thick mode -automatically regardless of the actual media weight.</dd> -</dl> - -<dl> -<dt><code>MediaWeight</code> (int or null)</dt> -<dd>The weight of the media in grams per square meter. Null (the default) -indicates that the weight is of no importance. If the specified media -weight is greater than 105 (that is, the value of the compilation default -<code>BJC</code>???<code>_MEDIAWEIGHT_THICKLIMIT</code>) then the -printer will be set to use thick paper.</dd> -</dl> - -<dl> -<dt><code>PrintQuality</code> (string)</dt> -<dd>The quality of printing.</p> -<table> -<tr colspan="4"> - <th>Value</th> - <th>bjc600</th> - <th>bjc800</th> - <th>Comments</th> -</tr> -<tr> - <td><code>Low</code></td> - <td> </td> - <td align="center"><b>X</b></td> - <td>Has the effect of making only two printing passes instead of four, so should be twice the speed; known as "CN" (Color Normal) mode</td> -</tr> -<tr> - <td><code>Draft</code></td> - <td align="center"><b>X</b></td> - <td align="center"><b>X</b></td> - <td>Unlights the "HQ" light on a BJC-600</td> -</tr> -<tr> - <td><code>Normal</code></td> - <td align="center"><b>X</b></td> - <td align="center"><b>X</b></td> - <td>Default for both drivers; lights the "HQ" light on a BJC-600</td> -</tr> -<tr> - <td><code>High</code></td> - <td align="center"><b>X</b></td> - <td align="center"><b>X</b></td> - <td>Means 200% black and 100% CMY; lights the "Bk+" light on a BJC-600</td> -</tr> -</table> -</dd> - -</dl> - -<dl> -<dt><code>DitheringType</code> (string) -<dd>Dithering algorithm from between "<code>Floyd-Steinberg</code>" and -"<code>None</code>". "<code>None</code>" is the default for 1/1 print -mode, "<code>Floyd-Steinberg</code>" for other modes. At the moment -this parameter is read-only, though no error is generated if one tries to -change it. This parameter is not of much value at the moment and is here -mainly to reserve the name for future addition of dithering algorithms. -</dl> - -<dl> -<dt><code>PrintColors</code> (int) -<dd>Mask for printing color. If 0, use black for any color; otherwise the -value must be the sum of any of 1 (cyan), 2 (magenta), 4 (yellow) and 8 -(black), indicating which colors will be used for printing. When printing -colour, only colours specified will be printed (this means that some planes -will be missing if a color's value above is omitted). When printing grays, -black is used if it is present in the <code>PrintColors</code>; -otherwise, the image is printed by superimposing each requested color. -</dl> - -<dl> -<dt><code>MonochromePrint</code> (bool) -<dd><b>For <tt>bjc600</tt> only</b>, <code>false</code> by default. -Substitute black for Cyan, Magenta and Yellow when printing -- useful, for -example, to get some monochrome output of a dithered printing This is a -hardware mechanism as opposed to the previous software one. I think that -using this or setting <code>PrintColors</code> to 0 will give the same -results. -</dl> - -<p> -Note that the <code>MediaType</code> and <code>ThickMedia</code> -options will be replaced by the use of the device -<code>InputAttributes</code> and <code>OutputAttributes</code> as -soon as possible. Please note too that the print mode may be reset at the -start of printing, not at the end. This is the expected behaviour. If you -need to reset the printer to its default state, simply print a file that -does just a <code>showpage</code>.</p> - -<h4><a name="BJC_device_info"></a>Device information</h4> - -<p> -Here is other information published by the driver that you will find -in the <code>deviceinfo</code> dictionary.</p> - -<dl> -<dt><code>OutputFaceUp</code> (bool) -<dd>This has the boolean value <code>true</code>, indicating that the -sheets are stacked face up. -</dl> - -<dl> -<dt><code>Version</code> (float) -<dd>In the form <b>M.</b><em>mm</em>pp, where <b>M</b> is the major -version, <em>mm</em> the bjc driver's minor version, and pp the specific -driver minor version (that is, <code>M.</code><em>mm</em> will always be -the same for the <code>bjc600</code> and <code>bjc800</code> -drivers). -</dl> - -<dl> -<dt><code>VersionString</code> (string) -<dd> A string showing the driver version and other indications. At the -moment, things like "a" or "b" may follow the version to indicate alpha or -beta versions. The date of the last change to this version is given in the -form MM/DD/YY (no, it won't adapt to your locale). -</dl> - -<h4><a name="BJC_HW_margins"></a>Hardware margins</h4> - -<p> -The BJC printers have top and bottom hardware margins of 3mm and 7.1mm -respectively (Canon says 7mm, but this is unusable because of the rounding -of paper sizes to PostScript points). The left margin is 3.4mm for A4 and -smaller paper sizes, 6.4mm for U.S. paper sizes, envelopes and cards. It -is 4.0mm for A3 paper on the BJC-800.</p> - -<p> -The maximum printing width of a BJC-600 printer is 203mm. The maximum -printing width of a BJC-800 printer is 289mm on A3 paper, 203mm on -U.S. letter and ISO A4 paper.</p> - -<h4><a name="BJC_PPD"></a>PostScript printer description (PPD) files</h4> - -<p> -The files <code>CBJC600.PPD</code> and <code>CBJC800.PPD</code> (whose -long names are, respectively, <code>Canon_BubbleJetColor_600.ppd</code> -and <code>Canon_BubbleJetColor_800.ppd</code>) are PPD files to drive the -features of the <code>bjc600</code> and <code>bjc800</code> drivers. -They can be used, for example, on NextStep systems (presumably on OpenStep -systems too) and on Unix systems with Adobe's TranScript and -<code>pslpr</code> (not tested). The files are not complete at the -moment. Please note that NextStep's printing interface does not -correctly enforce constraints specified in these files (in UIConstraints -descriptions): you must force yourself to use valid combinations of -options.</p> - -<h4><a name="BJC_PPD_custom"></a>Customizing the PPD files</h4> - -<p> -By default the PPD files are set for U.S. letter size paper, and they use a -normalized transfer function. If you choose to use A4 printing by default, -you must replace "<code>Letter</code>" with "<code>A4</code>" in -these (noncontiguous) lines:</p> - -<blockquote> - [...]<br> -<code>*DefaultPageSize: Letter<br></code> - [...]<br> -<code>*DefaultRegion: Letter<br></code> - [...]<br> -<code>*DefaultImageableArea: Letter</code><br> - [...]<br> -</blockquote> - -<p> -Some versions of Ghostscript have problems with normalized colors, which -makes them add magenta in gray levels. If you experience this problem, -in the PPD file replace the line</p> - -<blockquote><code> -*DefaultTransfer: Normalized -</code></blockquote> - -<p> -with the alternate line</p> - -<blockquote><code> -*DefaultTransfer: Null -</code></blockquote> - -<p> -The "thick media" option is implemented by choosing a value of 120 or 80 -(for thick and thin media respectively) for the <code>MediaWeight</code> -feature of the drivers. If you ever change the threshold for thick media -in the driver code, you may need to change the values in the PPD files too.</p> - -<p> -All customization should be done using the "<code>*Include:</code>" -feature of PPD files so that your local changes will be retained if you -update the PPD files.</p> - -<h3><a name="BJC_bugs"></a>How to report problems</h3> - -<p> -Yves Arrouye no longer maintains this driver, and will not answer questions -about it. If you are posting a question about it in a public form, please -be as descriptive as possible, and please send information that can be used -to reproduce the problem. Don't forget to say which driver you use, and in -what version. Version information can be found in the source code of the -driver or by issuing the following command in a shell:</p> - -<blockquote><code> -echo "currentpagedevice /VersionString get ==" | gs -q -sDEVICE=bjc600 - -</code></blockquote> - -<h3><a name="BJC_acks"></a>Acknowledgements</h3> - -<p> -I am particularly grateful to Yoshio Kuniyoshi <<a -href="mailto:yoshio@nak.math.keio.ac.jp">yoshio@nak.math.keio.ac.jp</a>> -without whom I'd never make these drivers, and also to L. Peter Deutsch, -who answered all my (often silly) questions about Ghostscript's driver -interface.</p> - -<p> -Thanks also to the people who volunteered to beta-test the v2.x BJC -drivers: David Gaudine -<<a href="mailto:david@donald.concordia.ca">david@donald.concordia.ca</a>>, -Robert M. Kenney <<a href="mailto:rmk@unh.edu">rmk@unh.edu</a>>, -James McPherson -<<a href="mailto:someone@erols.com">someone@erols.com</a>> -and Ian Thurlbeck -<<a href="mailto:ian@stams.strath.ac.uk">ian@stams.strath.ac.uk</a>> -(listed alphabetically) were particularly helpful by discovering bugs and -helping find out exact paper margins on printers I don't have access to.</p> - -<p> -And many thanks to Klaus-Gunther Hess -<<a href="mailto:ghess@elmos.de">ghess@elmos.de</a>> for looking -at the dithering code and devising a good CMYK dithering algorithm for the -Epson Stylus Color, which I then adapted to the code of these drivers.</p> - -<hr> - -<h2><a name="STC_epson_stylus"></a>Epson Stylus color printer (see also <code>uniprint</code>)</h2> - -<p> -This section was contributed by Gunther Hess -<<a href="mailto:ghess@elmos.de">ghess@elmos.de</a>>, who also wrote -<code>uniprint</code>, a later set of drivers. You should probably see -the section on <a href="#Uniprint"><code>uniprint</code></a> for whether -it might be better for your uses than this driver.</p> - -<h3><a name="STC_usage"></a>Usage</h3> - -<p> - -This driver is selected with "<code>-sDEVICE=stcolor</code>", producing -output for an Epson Stylus Color at 360dpi resolution by default. But it -can do much more with this printer, and with significantly better quality, -than with the default mode; and it can also produce code for monochrome -versions of the printer. This can be achieved via either command-line -options or Ghostscript input. For convenience a PostScript file is -supplied for use as an initial input file. Try the following command:</p> - -<blockquote> -<code>gs -sDEVICE=stcolor -r</code><b>{Xdpi}</b><code>x</code><b>{Ydpi}</b><code> stcolor.ps</code> <b>{YourFile.ps}</b> -</blockquote> - -<p> -where <b>{Xdpi}</b> is one of 180, 360, or 720 and <b>{Ydpi}</b> is one of -90, 180, 360, or 720. The result should be significantly better. You may -use <code>stcolor.ps</code> with other devices too, but I do not -recommend this, since it does nothing then. <code>stcolor.ps</code> -should be available with binary distributions and should reside in the same -directory as other Ghostscript initialization files or in the same -directory as the files to be printed. Thus if Ghostscript is part of your -printer-spooler, you can insert</p> - -<blockquote><code> -(stcolor.ps) findlibfile { pop run } if pop -</code></blockquote> - -<p> -in files you want to use the improved algorithms. You may want to adapt -<code>stcolor.ps</code> file to your specific needs. The methods and -options for this are described here, but this description is restricted to -Ghostscript options, while their manipulation at the PostScript level is -documented in the material on <a href="Language.htm">the relationship of -Ghostscript and PostScript</a> and in <code>stcolor.ps</code>.</p> - -<h3><a name="STC_options"></a>Options</h3> - -<p> -Now to explain the options (as written on my UNIX system). The order is -somehow related to their use during the printing process:</p> - -<dl> -<dt><code>-dUnidirectional</code> -<dd>Force unidirectional printing, recommended for transparencies -</dl> - -<dl> -<dt><code>-dMicroweave</code> -<dd>Enable the printer's "microweave" feature; see -"<a href="#What_is_weaving">What is weaving?</a>" below. -</dl> - -<dl> -<dt><code>-dnoWeave</code> -<dd>Disable any Weaving (overrides <code>-dMicroweave</code>) -</dl> - -<dl> -<dt><code>-dSoftweave</code> -<dd>Enable the driver's internal weaving. Note that <code>Softweave</code> works <b>only</b> with the original Stylus Color and the PRO-Series. -</dl> - -<dl> -<dt><code>-sDithering=</code><em>{name}</em> -<dd>Select another dithering algorithm (name) from among: -<blockquote> -<table> - - <tr> - <th width="25%">Dithering name</th> - <th width="75%">Comments</th> - </tr> -<tr> - <td><code>gscmyk</code></td> - - <td>fast color output, CMYK process color model (default)</td> -</tr> -<tr> - <td><code>gsmono</code></td> - - <td>fast monochrome output</td> -</tr> -<tr> - <td><code>gsrgb</code></td> - - <td>fast color output, RGB process color model</td> -</tr> -<tr> - <td><code>fsmono</code></td> - - <td>Floyd-Steinberg, monochrome</td> -</tr> -<tr> - <td><code>fsrgb</code></td> - - <td>Floyd-Steinberg, RGB process color model (almost identical to the <code>cdj550</code>/<code>bjc</code> algorithm)</td> -</tr> -<tr> - <td><code>fsx4</code></td> - - <td>Floyd-Steinberg, CMYK process color model (shares code with <code>fsmono</code> and <code>fsrgb</code>, but is algorithmically really bad)</td> -</tr> -<tr> - <td><code>fscmyk</code></td> - - <td>Floyd-Steinberg, CMYK process color model and proper modifications for CMYK</td> -</tr> -<tr> - <td><code>hscmyk</code></td> - - <td>modified Floyd-Steinberg with CMYK model ("hs" stands for "hess" not for "high speed", but the major difference from <code>fscmyk</code> is speed)</td> -</tr> -<tr> - <td><code>fs2</code></td> - - <td>algorithm by Steven Singer (RGB) should be identical to <code>escp2cfs2</code>.</td> -</tr> -</table> -</blockquote> -</dl> - -<dl> -<dt><code>-dBitsPerPixel=</code><em>{1...32}</em> -<dd>number of bits used for pixel storage; the larger the value, the better -the quality -- at least in theory. In <code>fsrgb</code> one can gain -some speed by restricting to 24 bits rather than the default 30. -</dl> - -<dl> -<dt><code>-dFlag0</code> -<dd>causes some algorithms to select a uniform initialisation rather than a -set of random values. May yield a sharper image impression at the cost of -dithering artifacts. (Applies to <code>hscmyk</code> and all fs modes, -except for fs2, which always uses a constant initialization.) -</dl> - -<dl> -<dt><code>-dFlag1</code> ... <code>-dFlag4</code> -<dd>Available for future algorithms. -</dl> - -<dl> -<dt><code>-dColorAdjustMatrix='{</code><em>three, nine, or sixteen -floating-point values</em><code>}'</code> -<dd>This is a matrix to adjust the colors. Values should be between -1.0 -and 1.0, and the number of values depends on the color model the selected -algorithm uses. In RGB and CMYK modes a matrix with 1.0 on the diagonal -produces no transformation. This feature is really required, but I could -not identify a similar feature at the language level, so I implemented it, -but I don't know reasonable values yet. -</dl> - -<dl> -<dt><code>-dCtransfer='{</code><em>float float ...</em><code>}'</code> or -<dt><code>-dMtransfer=</code>..., <code>-dY</code>..., <code>-dK</code>... or -<dt><code>-dRtransfer='{</code><em>float float ...</em><code>}'</code> or -<dt><code>-dG</code>..., <code>-dB</code>... or -<dt><code>-dKtransfer='{</code><em>float float ...</em><code>}'</code> -<dd>Which you use depends on the algorithm, which may be either either -CMYK, RGB or monochrome. The values are arrays of floats in the range from -0 to 1.0, representing the visible color intensity for the device. One may -achieve similar effects with <code>setcolortransfer</code> at the -language level, but this takes more time and the underlying code for the -driver-specific parameters is still required. The size of the arrays is -arbitrary and the defaults are "<code>{0.0 1.0}</code>", which is a -linear characteristic. Most of the code in <code>stcolor.ps</code> are -better transfer arrays. -</dl> - -<dl> -<dt><code>-dKcoding='{</code><em>float...</em><code>}'</code> -<dt><code>-dC</code>..., <code>-dM</code>... etc. -<dd>Arrays between 0.0 and 1.0, controlling the internal coding of the -color values. Clever use of these arrays may yield further enhancements, -but I have no experience yet. (To be discontinued with version 2.x.) -</dl> - -<dl> -<dt><code>-sModel=st800</code> -<dd>Causes output to be suitable for the monochrome Stylus 800 (no weaving, -no color). -</dl> - -<dl> -<dt><code>-sOutputCode=</code><em>{name}</em> -<dd>Can be either "<code>plain</code>", "<code>runlength</code>" or -"<code>deltarow</code>" and changes the ESC/P2 coding technique -used by the driver. The default is to use runlength encoding. -"<code>plain</code>" selects uncompressed encoding and generates -enormous amounts of data. -</dl> - -<dl> -<dt><code>-descp_Band=</code><em>1/8/15/24</em> -<dd>Number of nozzles of scanlines used in printing, Useful only with -<code>-dnoWeave</code>. Larger Values yield smaller code, but this -doesn't increase the printing speed. -</dl> - -<dl> -<dt><code>-descp_Width=</code><em>N</em> -<dd>Number of pixels Printed in each scan Line. (Useful only when tuning -margins; see below) -</dl> - -<dl> -<dt><code>-descp_Height=</code><em>pixels</em> -<dd>Length of the entire page in pixels. (Parameter of -"<code>ESC(C</code>" in default initialization.) -</dl> - -<dl> -<dt><code>-descp_Top=</code><em>scan lines</em> -<dd>Top margin in scan lines. (First parameter of "<code>ESC(c</code>" -in default initialization.) -</dl> - -<dl> -<dt><code>-descp_Bottom=</code><em>scan lines</em> -<dd>Bottom margin in scan lines. (Second parameter of -"<code>ESC(c</code>" in default initialization.) -</dl> - -<dl> -<dt><code>-sescp_Init=</code>"<em>string</em>" -<dd>Override for the initialization sequence. (Must set graphics mode 1 -and units.) -</dl> - -<dl> -<dt><code>-sescp_Release=</code>"<em>string</em>" -<dd>Overrides the release sequence, "<code>ESC @ FF</code>" by -default. -</dl> - -<p> -ESC/P2 allows any resolutions to be valid in theory, but only -<code>-r360x360</code> (the default) and <code>-r720x720</code> (not -on STC-IIs ? and st800) are known to work with most printers.</p> - -<blockquote> -<table> -<tr> - <th colspan="4">Valid option combinations – Stylus I & Pro-Series only</th> - </tr> -<tr> - <td>Resolution</td> - <td><code>escp_Band</code></td> - <td>Weave usable</td> - <td><code>escp_Band</code> &<br>number of passes</td> -</tr> -<tr> - <td>180x90</td> - <td>15</td> - <td><code>noWeave</code></td> - <td> </td> -</tr> -<tr> - <td>180x180</td> - <td>1, 8, 24</td> - <td><code>noWeave</code>, <code>Microweave</code></td> - <td>15/2 <code>SoftWeave</code></td> -</tr> -<tr> - <td>180x360</td> - <td> </td> - <td> </td> - <td>15/4 <code>SoftWeave</code></td> -</tr> -<tr> - <td>180x720</td> - <td> </td> - <td> </td> - <td>15/8 <code>SoftWeave</code></td> -</tr> -<tr> - <td>360x90</td> - <td>15</td> - <td><code>noWeave</code></td> - <td> </td> -</tr> -<tr> - <td>360x180</td> - <td>1, 8, 24</td> - <td><code>noWeave</code>, <code>Microweave</code></td> - <td>15/2 <code>SoftWeave</code></td> -</tr> -<tr> - <td>360x360</td> - <td>1, 8, 24</td> - <td><code>noWeave</code>, <code>Microweave</code></td> - <td>15/4 <code>SoftWeave</code></td> -</tr> -<tr> - <td>360x720</td> - <td> </td> - <td> </td> - <td>15/8 <code>SoftWeave</code></td> -</tr> -<tr> - <td>720x90</td> - <td>15</td> - <td><code>noWeave</code></td> - <td> </td> -</tr> -<tr> - <td>720x180</td> - <td> </td> - <td> </td> - <td>15/2 <code>SoftWeave</code></td> -</tr> -<tr> - <td>720x360</td> - <td> </td> - <td> </td> - <td>15/4 <code>SoftWeave</code></td> -</tr> -<tr> - <td>720x720</td> - <td>1</td> - <td><code>noWeave</code>, <code>Microweave</code></td> - <td>15/8 <code>SoftWeave</code></td> -</tr> -</table> -</blockquote> - -<blockquote> -<b>Beware:</b> there are only few validity checks for parameters. A good -example is <code>escp_Band</code>: if you set this, the driver uses your -value even if the value is not supported by the printer. <b>You asked for -it and you got it!</b> -</blockquote> - -<h3><a name="STC_FAQ"></a>Application note and FAQ</h3> - -<p> -Quite a bunch of parameters. Hopefully you never need any of them, besides -feeding <code>stcolor.ps</code> to Ghostscript in front of your input.</p> - -<p> -After answering some questions over fifty times I prepared a FAQ. Here is -version 1.3 of the FAQ, as of <code>stcolor</code> version 1.20 (for -Ghostscript 3.50).</p> - -<h4><a name="STC_FAQ_A3"></a>Support for A3 paper</h4> - -<p> -Yes, this driver supports the A3-size printer: merely set the required -pagesize and margins. A simple way to do this is to specify the -command-line switch "<code>-sPAPERSIZE=a3</code>" or include the -procedure call "<code>a3</code>" in the PostScript prolog section. To -optimize the printable area or set the proper margins, see the next -paragraph.</p> - -<h4><a name="STC_FAQ_margins"></a>Margins, PageSize</h4> - -<p> -I refuse to add code to <code>stcolor</code> that tries to guess the -proper margins or page size, because I found that such guessing is usually -wrong and needs correction in either the source or the parameters. You can -modify <code>stcolor.ps</code> to do that, however. After the line</p> - -<blockquote><code> -mark % prepare stack for "putdeviceprops" -</code></blockquote> - -<p> -insert these lines, which define page size and margins in points:</p> - -<blockquote> -<pre>/.HWMargins [9.0 39.96 12.6 9.0] % Left, bottom, right, top (1/72") -/PageSize [597.6 842.4] % Paper, including margins (1/72") -/Margins [ % neg. Offset to Left/Top in Pixels - 4 index 0 get STCold /HWResolution get 0 get mul 72 div neg - 5 index 3 get STCold /HWResolution get 1 get mul 72 div neg -]</pre></blockquote> - -<p> -Feel free to change the values of <code>.HWMargins</code> and -<code>PageSize</code> to match your needs; the values given are the -defaults when the driver is compiled with "<code>-DA4</code>". This -option or its omission may cause trouble: the Stylus Color can print up to -exactly 8 inches (2880 pixels) at 360dpi. The remaining paper is the -margin, where the left margin varies only slightly with the paper size, -while the right margin is significantly increased for wider paper, such as -U.S. letter size.</p> - -<p> -<b>Note</b> that if you are using an ISO paper size with a version of -<code>stcolor</code> after 1.20 and compiled without -"<code>-DA4</code>", then the default margin is too large, and you need -to add the proper "<code>.HWMargins</code>" to the command line or to -<code>stcolor.ps</code>.</p> - -<h4><a name="STC_FAQ_II_IIS_1500"></a>Stylus Color II / IIs and 1500</h4> - -<p> -First the good news: the driver can print on the Stylus Color II. -Now the bad news:</p> -<ul> -<li>According to Epson support the driver "abuses" the color -capabilities. (See "Future Plans" for details.)</li> -<li>You need some parameters on the command line (or in -<code>stcolor.ps</code>).</li> -<li>I doubted that it would be usable with the Stylus Color IIs, but -it <b>is</b> usable and suffers from mixing problems!</li> -</ul> - -<p> - -To make things work, you <b>MUST</b> disable the driver's internal -weaving (<code>Softweave</code>), in one of these two ways:</p> - -<blockquote> -<code>gs -dMicroweave</code> ...<br> -<code>gs -dnoWeave -descp_Band=1</code> ... -</blockquote> - -<p> -Version 1.90, current as of Ghostscript 5.10, fixes this bug by new default -behaviour. I experienced significantly increased printing speed with the -second variant on the old Stylus Color, when printing mostly monochrome -data.</p> - -<h3><a name="STC_recommendations"></a>Recommendations</h3> - -<p> -The next section is a contribution from Jason Patterson <jason@reflections.com.au> -who evaluated a previous version (1.17). Ghostscript was invoked as follows:</p> - -<blockquote><dl compact> -<dt><code>gs</code> -<dd><code>-sDEVICE=stcolor -r720x720 --sDithering=</code>... <code>-sOutputFile=escp.out stcolor.ps -whatsoever.ps</code> - -</dl></blockquote> - -<p> -where "..." is the name of the desired algorithm. -<code>stcolor.ps</code> was omitted for the gs-algorithms -(<code>gsmono</code>, <code>gsrgb</code> and <code>gscmyk</code>), -for which it is useless and would not allow the selection of -"<code>gscmyk</code>".</p> - -<h4><a name="STC_dither_experiment"></a>Color dithering experiments with -<code>gdevstc</code> 1.21</h4> - -<p> -Here are data about the EPSON Stylus Color driver's different dithering -methods, based on a little experiment using four good quality scanned -images of quite varied nature, to begin with, a summary of the results of -the four experiments. <b>Sanity note:</b> the results here are from only -four images and a total of 24 printouts (eight on 720dpi paper, sixteen on -plain paper). Your results will almost certainly vary, and your standards -might not be the same as mine, so use these results only as a guide, not as -a formal evaluation.</p> - -<blockquote> -<table> -<tr> - <th colspan="2">Quality of output by method</th> -</tr> -<tr> - <td><code>gsmono</code></td> - <td>Pretty much what you'd expect from a mono ordered pattern. - Looks like what a lot of mono laser printers produce.</td> -</tr> -<tr> - <td><code>fsmono</code></td> - <td>Excellent for monochrome.</td> -</tr> -<tr> - <td><code>gscmyk</code></td> - <td>Not very good, but expected from an ordered pattern.</td> - </tr> -<tr> - <td><code>gsrgb</code></td> - <td>A little better than <code>gscmyk</code>. More consistent - looking.</td> -</tr> -<tr> - <td><code>fs2</code></td> - <td>Good, but not quite as good as <code>fsrgb</code>. Gets the - brightness wrong: too light at 720dpi, too dark at 360dpi.</td> -</tr> -<tr> - <td><code>fsrgb</code></td> - <td>Very good, but a little too dark and has a slight blue tint.</td> -</tr> -<tr> - <td><code>hscmyk</code></td> - <td>Excellent. Slightly better than <code>fsrgb</code> and - <code>fs2</code>. Better than <code>fscmyk</code> on - some images, almost the same on most.</td> -</tr> -<tr> - <td><code>fscmyk</code></td> - <td>Best. Very, very slightly better than <code>hscmyk</code>. - On some images nearly as good as the EPSON demos done with - the MS Windows driver.</td> - </tr> -</table> -</blockquote> - -<blockquote> -<table> -<tr> - <th colspan="2">Overall visual quality (1-10), best to worst</th> -</tr> -<tr> - <td><b>Monochrome</b></td> - <td></td> -</tr> -<tr> - <td><code>fsmono</code></td> - <td><code>******************</code></td> -</tr> -<tr> - <td><code>gsmono</code></td> - <td><code>**********</code></td> -</tr> -<tr> - <td> </td> - <td><code>0 1 2 3 4 5 6 7 8 9 10</code></td> -</tr> -<tr> - <td><b>Colour</b></td> - <td></td> - </tr> -<tr> - <td><code>fscmyk</code></td> - <td><code>*******************</code></td> -</tr> -<tr> - <td><code>hscmyk</code></td> - <td><code>*******************</code></td> -</tr> -<tr> - <td><code>fsrgb</code></td> - <td><code>******************</code></td> -</tr> -<tr> - <td><code>fs2</code></td> - <td><code>*****************</code></td> -</tr> -<tr> - <td><code>gsrgb</code></td> - <td><code>**********</code></td> -</tr> -<tr> - <td><code>gscmyk</code></td> - <td><code>*********</code></td> -</tr> -<tr> - <td> </td> - <td><code>0 1 2 3 4 5 6 7 8 9 10</code></td> -</tr> -</table> -</blockquote> - -<h3><a name="STC_color_transform"></a>Color transformation</h3> - -<p> -In the initial version of the driver distributed with Ghostscript 3.33, the -parameter "<code>SpotSize</code>" was the only way to manipulate the -colors at the driver level. According to the parameters enumerated above, -this has changed significantly with version 1.16 and above as a result an -ongoing discussion about dithering algorithms and "false color" on the -Epson Stylus Color. This initiated the transformation of the -<code>stcolor</code> driver into a framework for different dithering -algorithms, providing a generalized interface to the internal Ghostscript -color models and the other data structures related to Ghostscript drivers.</p> - -<p> -The main thing such a framework should be able to do is to deliver the -values the dithering algorithm needs; and since this directly influences -the optical image impression, this transformation should be adjustable -without the need for recompilation and relinking. In general the process -can be described as follows:</p> - -<blockquote><table> -<tr> - <td colspan="3"><code>ColorAdjustMatrix</code></td> - <td align="center">Coding</td> - <td colspan="3"> </td> - <td align="center">Transfer</td> - <td colspan="3"> </td> -</tr> -<tr> - <td>|</td> - <td align="center">Ghostscript color</td> - <td>|</td> - <td align="center">=></td> - <td>|</td> - <td align="center">Ghostscript raster</td> - <td>|</td> - <td align="center">=></td> - <td>|</td> - <td align="center">Dithering data</td> - <td>|</td> -</tr> -<tr> - <td>|</td> - <td> </td> - <td>|</td> - <td> </td> - <td>|</td> - <td align="center">1/2/4/8/16/32-bit</td> - <td>|</td> - <td> </td> - <td>|</td> - <td> </td> - <td>|</td> -</tr> -<tr> - <td>|</td> - <td align="center">1/3/4 16-bit values</td> - <td>|</td> - <td> </td> - <td>|</td> - <td align="center">1/3/4 values</td> - <td>|</td> - <td> </td> - <td>|</td> - <td align="center">(arbitrary type)</td> - <td>|</td> -</tr> -</table> -</blockquote> - -<p> -Due to the limitations on raster storage, information is lost in the first -transformation step, except for the 16-bit monochrome mode. So any color -adjustment should take place before this step and this is where the optional -<code>ColorAdjustMatrix</code> works.</p> - -<p> -The first transformation step, called "coding", is controlled by the -<code>?coding</code> arrays. The decoding process expands the range of -values expontentially to a larger range than that provided by the initial -Ghostscript color model, and is therefore a reasonable place to make -device- or algorithm-specific adjustments. This is where the -<code>?transfer</code> arrays are used. Array access might be not the -fastest method, but its generality is superior, so this step is always -based upon internally algorithm-specific array access. If 8 bits are stored -per color component and if the algorithm uses bytes too, the second -transformation is included within the first, which saves significant -computation time when printing the data.</p> - -<h3><a name="STC_CAM"></a><code>ColorAdjustMatrix</code></h3> - -<p> -The driver supports different values for <code>ProcessColorModel</code>, -which raises the need for different color adjustments. Here -"<code>CAM</code>" stands for "<code>ColorAdjustMatrix</code>".</p> - -<dl> -<dt><code>DeviceGray</code> (three floats) -<dd><pre>if ((r == g) && (g == b)) - K' = 1.0 - R; -else - K' = 1.0 - CAM[0] * R + CAM[1] * G + CAM[2] * B;</pre> - -<p> -According to the <a href="Drivers.htm">documentation on drivers</a>, the -latter (the "else" clause) should never happen.</p> -</dl> - -<dl> -<dt><code>DeviceRGB</code> (nine floats) -<dd><pre>if((r == g) && (g == b)) - R' = B' = G' = R; -else - R' = CAM[0]*R + CAM[1]*G + CAM[2]*B; - G' = CAM[3]*R + CAM[4]*G + CAM[5]*B; - B' = CAM[6]*R + CAM[7]*G + CAM[8]*B;</pre> - -<p> -The printer always uses four inks, so a special treatment of black is -provided. Algorithms may take special action if R, G, and B are all -equal.</p> -</dl> - -<dl> -<dt><code>DeviceCMYK</code> (sixteen floats) -<dd> -<pre>if((c == m) && (m == y)) - K' = max(C,K); - C' = M' = Y' = 0; -else - K = min(C,M,Y); - if((K > 0) && ColorAdjustMatrix_present) { => UCR - C -= K; - M -= K; - Y -= K; - } - - C' = CAM[ 0]*C + CAM[ 1]*M + CAM[ 2]*Y + CAM[ 3]*K; - M' = CAM[ 4]*C + CAM[ 5]*M + CAM[ 6]*Y + CAM[ 7]*K; - Y' = CAM[ 8]*C + CAM[ 9]*M + CAM[10]*Y + CAM[11]*K; - K' = CAM[12]*C + CAM[13]*M + CAM[14]*Y + CAM[15]*K;</pre> - -<p> -Again we have a special black treatment. "<code>max(C,K)</code>" was introduced -because of a slight misbehaviour of Ghostscript, which delivers -black under certain circumstances as (1,1,1,0). Normally, when -no special black separation and undercolor removal procedures -are defined at the PostScript level, either (C,M,Y,0) or (0,0,0,K) -values are mapped. This would make the extended <code>ColorAdjustMatrix</code> -quite tedious, and so during mapping, black separation is done for -(C,M,Y,0) requests; and if there is a <code>ColorAdjustMatrix</code>, undercolor -removal is used too. In other words the default matrix is:</p> - -<blockquote><table> -<tr> <td>1</td><td>0</td><td>0</td><td>1</td></tr> -<tr> <td>0</td><td>1</td><td>0</td><td>1</td></tr> -<tr> <td>0</td><td>0</td><td>1</td><td>1</td></tr> -<tr> <td>0</td><td>0</td><td>0</td><td>1</td></tr> -</table></blockquote> - -<p> -and it is applied to CMYK values with separated and removed black. Raising -the CMY coefficients while lowering the K coefficients reduces black and -intensifies color. But be careful, because even small deviations from the -default cause drastic changes.</p> -</dl> - -<p> -If no <code>ColorAdjustMatrix</code> is set, the matrix computations are -skipped. Thus the transformation reduces to range inversion in monochrome -mode and black separation in CMYK mode.</p> - -<h3><a name="STC_RGBCMYK_coding"></a>RGB / CMYK coding and transfer, and <code>BitsPerPixel</code></h3> - -<p> -These two (groups of) parameters are arrays of floating-point numbers in -the range 0.0 to 1.0. They control the truncation to the desired number of -bits stored in raster memory (<code>BitsPerPixel</code>) and the ink -density. The "truncation" may become a nonlinear function if any of the -<code>?coding</code> arrays is set. Assume the following Ghostscript -invocation:</p> - -<blockquote><pre>gs -sDEVICE=stcolor -sDithering=fscmyk -dBitsPerPixel=16 \ - -dKcoding='{ 0.0 0.09 0.9 1.0 }' \ - -dMcoding='{ 0.0 0.09 0.9 1.0 }' \ - -dKtransfer='{ 0.0 0.09 0.9 1.0 }' \ - -dYtransfer='{ 0.0 0.09 0.9 1.0 }'</pre> -</blockquote> - -<p> -We may have either or both of <code>?coding</code> and -<code>?transfer</code>, giving four possible combinations. (These four -combinations appear in the given example.) The resulting mapping appears -in the following tables, where except for the internal Indices (4 -components × 4 bits = 16 <code>BitsPerPixel</code>), all values -are normalized to the range 0 to 1. The actual range is 0 to 65535 for the -Ghostscript color and 0 to 16777215 for the ink values delivered to the -<code>fscmyk</code> algorithm. Sorry for the bunch of numbers -following, but you may try this example in conjunction with -<code>stcinfo.ps</code>, which should give you a graphical printout of -the following numbers when you issue a <code>showpage</code> command.</p> - -<blockquote> -<table> -<tr> - <th></th> - <th colspan="3">Cyan</th> - <th colspan="3">Magenta</th> -</tr> -<tr> - <th>CI/15</th> - <th>gs_color_values</th> - <th>CI</th> - <th>Ink</th> - <th>gs_color_values</th> - <th>CI</th> - <th>Ink</th> -</tr> -<tr> - <td align="center">0.000</td> - <td align="center">0.000 - 0.062</td> - <td align="center">0</td> - <td align="center">0.000</td> - <td align="center">-0.123 - 0.123</td> - <td align="center">0</td> - <td align="center">0.000</td> -</tr> -<tr> - <td align="center">0.067</td> - <td align="center">0.063 - 0.125</td> - <td align="center">1</td> - <td align="center">0.067</td> - <td align="center">0.123 - 0.299</td> - <td align="center">1</td> - <td align="center">0.247</td> -</tr> -<tr> - <td align="center">0.133</td> - <td align="center">0.125 - 0.187</td> - <td align="center">2</td> - <td align="center">0.133</td> - <td align="center">0.299 - 0.365</td> - <td align="center">2</td> - <td align="center">0.351</td> -</tr> -<tr> - <td align="center">0.200</td> - <td align="center">0.188 - 0.250</td> - <td align="center">3</td> - <td align="center">0.200</td> - <td align="center">0.365 - 0.392</td> - <td align="center">3</td> - <td align="center">0.379</td> -</tr> -<tr> - <td align="center">0.267</td> - <td align="center">0.250 - 0.312</td> - <td align="center">4</td> - <td align="center">0.267</td> - <td align="center">0.392 - 0.420</td> - <td align="center">4</td> - <td align="center">0.406</td> -</tr> -<tr> - <td align="center">0.333</td> - <td align="center">0.313 - 0.375</td> - <td align="center">5</td> - <td align="center">0.333</td> - <td align="center">0.420 - 0.447</td> - <td align="center">5</td> - <td align="center">0.433</td> -</tr> -<tr> - <td align="center">0.400</td> - <td align="center">0.375 - 0.437</td> - <td align="center">6</td> - <td align="center">0.400</td> - <td align="center">0.447 - 0.475</td> - <td align="center">6</td> - <td align="center">0.461</td> -</tr> -<tr> - <td align="center">0.467</td> - <td align="center">0.438 - 0.500</td> - <td align="center">7</td> - <td align="center">0.467</td> - <td align="center">0.475 - 0.502</td> - <td align="center">7</td> - <td align="center">0.488</td> -</tr> -<tr> - <td align="center">0.533</td> - <td align="center">0.500 - 0.562</td> - <td align="center">8</td> - <td align="center">0.533</td> - <td align="center">0.502 - 0.529</td> - <td align="center">8</td> - <td align="center">0.516</td> -</tr> -<tr> - <td align="center">0.600</td> - <td align="center">0.563 - 0.625</td> - <td align="center">9</td> - <td align="center">0.600</td> - <td align="center">0.529 - 0.557</td> - <td align="center">9</td> - <td align="center">0.543</td> -</tr> -<tr> - <td align="center">0.667</td> - <td align="center">0.625 - 0.687</td> - <td align="center">10</td> - <td align="center">0.667</td> - <td align="center">0.557 - 0.584</td> - <td align="center">10</td> - <td align="center">0.571</td> -</tr> -<tr> - <td align="center">0.733</td> - <td align="center">0.688 - 0.750</td> - <td align="center">11</td> - <td align="center">0.733</td> - <td align="center">0.584 - 0.612</td> - <td align="center">11</td> - <td align="center">0.598</td> -</tr> -<tr> - <td align="center">0.800</td> - <td align="center">0.750 - 0.812</td> - <td align="center">12</td> - <td align="center">0.800</td> - <td align="center">0.612 - 0.639</td> - <td align="center">12</td> - <td align="center">0.626</td> -</tr> -<tr> - <td align="center">0.867</td> - <td align="center">0.813 - 0.875</td> - <td align="center">13</td> - <td align="center">0.867</td> - <td align="center">0.639 - 0.715</td> - <td align="center">13</td> - <td align="center">0.653</td> -</tr> -<tr> - <td align="center">0.933</td> - <td align="center">0.875 - 0.937</td> - <td align="center">14</td> - <td align="center">0.933</td> - <td align="center">0.715 - 0.889</td> - <td align="center">14</td> - <td align="center">0.778</td> -</tr> -<tr> - <td align="center">1.000</td> - <td align="center">0.938 - 1.000</td> - <td align="center">15</td> - <td align="center">1.000</td> - <td align="center">0.889 - 1.111</td> - <td align="center">15</td> - <td align="center">1.000</td> -</tr> -</table> -</blockquote> - -<p> -The difference between cyan and magenta is the presence of a coding array. -The coding process must map a range of color values to each of the sixteen -component indices. If no coding array is given, this is accomplished -by dividing by 4096, equivalent to a right shift by 12 bits. The -final ink density resides in the given interval and moves from the left to -the right side from 0 to 15. For magenta there is a coding array -and the ink value matches the center of the intervals. But the distribution -of the mapped intervals follows the given coding array and is nonlinear in -the linear color space of Ghostscript.</p> - -<p> -Now let us take a look at the case with transfer arrays:</p> - -<blockquote> -<table> -<tr> - <th></th> - <th colspan="3">Yellow</th> - <th colspan="3">Black</th> -</tr> -<tr> - <th>CI/15</th> - <th>gs_color_values</th> - <th>CI</th> - <th>Ink</th> - <th>gs_color_values</th> - <th>CI</th> - <th>Ink</th> -</tr> -<tr> - <td align="center">0.000</td> - <td align="center">0.000 - 0.062</td> - <td align="center">0</td> - <td align="center">0.000</td> - <td align="center">-0.123 - 0.123</td> - <td align="center">0</td> - <td align="center">0.000</td> -</tr> -<tr> - <td align="center">0.067</td> - <td align="center">0.063 - 0.125</td> - <td align="center">1</td> - <td align="center">0.018</td> - <td align="center">0.123 - 0.299</td> - <td align="center">1</td> - <td align="center">0.067</td> -</tr> -<tr> - <td align="center">0.13</td> - <td align="center">0.125 - 0.187</td> - <td align="center">2</td> - <td align="center">0.036</td> - <td align="center">0.299 - 0.365</td> - <td align="center">2</td> - <td align="center">0.133</td> -</tr> -<tr> - <td align="center">0.200</td> - <td align="center">0.188 - 0.250</td> - <td align="center">3</td> - <td align="center">0.054</td> - <td align="center">0.365 - 0.392</td> - <td align="center">3</td> - <td align="center">0.200</td> -</tr> -<tr> - <td align="center">0.267</td> - <td align="center">0.250 - 0.312</td> - <td align="center">4</td> - <td align="center">0.072</td> - <td align="center">0.392 - 0.420</td> - <td align="center">4</td> - <td align="center">0.267</td> -</tr> -<tr> - <td align="center">0.333</td> - <td align="center">0.313 - 0.375</td> - <td align="center">5</td> - <td align="center">0.090</td> - <td align="center">0.420 - 0.447</td> - <td align="center">5</td> - <td align="center">0.333</td> -</tr> -<tr> - <td align="center">0.400</td> - <td align="center">0.375 - 0.437</td> - <td align="center">6</td> - <td align="center">0.252</td> - <td align="center">0.447 - 0.475</td> - <td align="center">6</td> - <td align="center">0.400</td> -</tr> -<tr> - <td align="center">0.467</td> - <td align="center">0.438 - 0.500</td> - <td align="center">7</td> - <td align="center">0.414</td> - <td align="center">0.475 - 0.502</td> - <td align="center">7</td> - <td align="center">0.467</td> -</tr> -<tr> - <td align="center">0.533</td> - <td align="center">0.500 - 0.562</td> - <td align="center">8</td> - <td align="center">0.576</td> - <td align="center">0.502 - 0.529</td> - <td align="center">8</td> - <td align="center">0.533</td> -</tr> -<tr> - <td align="center">0.600</td> - <td align="center">0.563 - 0.625</td> - <td align="center">9</td> - <td align="center">0.738</td> - <td align="center">0.529 - 0.557</td> - <td align="center">9</td> - <td align="center">0.600</td> -</tr> -<tr> - <td align="center">0.667</td> - <td align="center">0.625 - 0.687</td> - <td align="center">10</td> - <td align="center">0.900</td> - <td align="center">0.557 - 0.584</td> - <td align="center">10</td> - <td align="center">0.667</td> -</tr> -<tr> - <td align="center">0.733</td> - <td align="center">0.688 - 0.750</td> - <td align="center">11</td> - <td align="center">0.920</td> - <td align="center">0.584 - 0.612</td> - <td align="center">11</td> - <td align="center">0.733</td> -</tr> -<tr> - <td align="center">0.800</td> - <td align="center">0.750 - 0.812</td> - <td align="center">12</td> - <td align="center">0.940</td> - <td align="center">0.612 - 0.639</td> - <td align="center">12</td> - <td align="center">0.800</td> -</tr> -<tr> - <td align="center">0.867</td> - <td align="center">0.813 - 0.875</td> - <td align="center">13</td> - <td align="center">0.960</td> - <td align="center">0.639 - 0.715</td> - <td align="center">13</td> - <td align="center">0.867</td> -</tr> -<tr> - <td align="center">0.933</td> - <td align="center">0.875 - 0.937</td> - <td align="center">14</td> - <td align="center">0.980</td> - <td align="center">0.715 - 0.889</td> - <td align="center">14</td> - <td align="center">0.933</td> -</tr> -<tr> - <td align="center">1.000</td> - <td align="center">0.938 - 1.000</td> - <td align="center">15</td> - <td align="center">1.000</td> - <td align="center">0.889 - 1.111</td> - <td align="center">15</td> - <td align="center">1.000</td> -</tr> -</table> -</blockquote> - -<p> -Yellow uses a transfer array. There is no linear correspondence between -the color and the ink values: this correspondence is defined through the -given array. In other words, the transfer arrays define a nonlinear ink -characteristic, which is exactly the same functionality that PostScript's -"(color)transfer" function provides.</p> - -<p> -While for yellow the intervals match the intervals used with cyan, for -black the intervals match the magenta intervals. But watch the -correspondence between the CI/15 values and the ink density for black: this -is a linear distribution in the ink domain.</p> - -<p> -Not a bad idea, I think. Consider the <code>fs2</code> algorithm: it -uses values in the range 0 to 255. If any transfer array were alone, some -of the 256 possible values would never be used and others would be used for -adjacent intervals several times. Establishing an identical coding array -solves this problem, so the full potential of the algorithm is used.</p> - -<p> -Another useful feature of the coding arrays is that they are internally -normalized to the range 0-1. In 720x720dpi mode the transfer arrays in -<code>stcolor.ps</code> limit the dot density to about 50%, so these -arrays end at 0.5 (and begin at 0.5 for RGB). Because of automatic -normalization, these arrays can also be used as coding arrays. But of -course in the <code>fs2</code> case mentioned above, values from 0 to -127 will never be delivered to the algorithm, while values 128-255 are -delivered for adjacent intervals.</p> - -<p> -To clarify the intended use of the three parameters (parameter groups), keep this in mind:</p> - -<blockquote><ul> -<li><code>ColorAdjustMatrix</code> is never used when transferring gray -values. This restricts it to what the name says: adjustment of colors, -that is, correction for miscolored ink. Do not use it for saturation or -brightness control.</li> - -<li><code>?transfer</code> arrays control the values delivered to the -driver, which in turn controls the ink quantity. Use these arrays to -control saturation and brightness. In general these arrays are identical -for all inks. If they differ they provide a simpler scheme for color -correction, which is not necessarily faster than the -<code>ColorAdjustMatrix</code>.</li> - -<li><code>?coding</code> arrays control the color value intervals mapped -to the internal color indices.</li> -</ul></blockquote> - -<h3><a name="What_is_weaving"></a>What is weaving?</h3> - -<p> -The Epson Stylus Color has a head assembly that contains two physically -identifiable heads, one for black and one for cyan, magenta, and yellow -(CMY). This makes four "logical" heads, one for each color component. -Each of these four heads has several jets at some vertical (Y) distance -from one another, so several horizontal lines can be printed of a given -color during one pass of the heads. From experience I think there are -fifteen jets per color, spaced at 1/90in.</p> - -<p> -So the question arises of how to print at a Y resolution of 360dpi with -90dpi jets. Simply by division one gets 360dpi/90dpi = 4, which tells us -that 4 passes of the head assembly are needed to achieve a Y resolution of -360dpi.</p> - -<p> -Weaving is the method of how the fifteen jets are used to print adjacent -horizontal rows separated here by 1/360 inch:</p> - -<blockquote> -<table> -<tr> - <th colspan="10">Print-head jets used with and without weaving</th> -</tr> -<tr> - <th></th> - <th></th> - <th colspan="4">Weaving</th> - <th colspan="4">noWeave</th> -</tr> -<tr> - <td></td> - <td>Pass</td> - <td>1</td> - <td>2</td> - <td>3</td> - <td>4</td> - <td>1</td> - <td>2</td> - <td>3</td> - <td>4</td> -</tr> -<tr> - <td colspan="10">Row</td> -</tr> -<tr> - <td align="center">0</td> - <td></td> - <td align="center">jet 0</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 0</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> -</tr> -<tr> - <td align="center">1</td> - <td></td> - <td align="center">--</td> - <td align="center">jet 1</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 0</td> - <td align="center">--</td> - <td align="center">--</td> -</tr> -<tr> - <td align="center">2</td> - <td></td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 2</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 0</td> - <td align="center">--</td> -</tr> -<tr> - <td align="center">3</td> - <td></td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 3</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 0</td> -</tr> -<tr> - <td align="center">4</td> - <td></td> - <td align="center">jet 1</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 1</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> -</tr> -<tr> - <td align="center">5</td> - <td></td> - <td align="center">--</td> - <td align="center">jet 2</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 1</td> - <td align="center">--</td> - <td align="center">--</td> -</tr> -<tr> - <td align="center">6</td> - <td></td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 3</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">--</td> - <td align="center">jet 1</td> - <td align="center">--</td> -</tr> -<tr> - <td colspan="10">...</td> -</tr> -</table> -</blockquote> - -<p> -Now let's assume that the dot diameter is different for each individual -jet, but the average among the jets matches the desired resolution. With -weaving, adjacent rows are printed by different jets, thus some averaging -takes place. Without weaving, adjacent rows are printed by the same jet -and this makes the dot diameter deviations visible as 1/90in stripes on -the paper.</p> - -<h3><a name="STC_print_modes"></a>Print mode parameters</h3> - -<p> -The parameters "<code>Unidirectional</code>", -"<code>Microweave</code>", "<code>noWeave</code>", -"<code>OutputCode</code>", "<code>Model</code>" and the given -resolution control the data generated for the printer.</p> - -<h4><a name="STC_unidirectional"></a><code>Unidirectional</code></h4> - -<p> -Simply toggles the unidirectional mode of the printer. Setting -"<code>Unidirectional</code>" definitely slows printing speed, but may -improve the quality. I use this for printing transparencies, where fast -head movement could smear the ink.</p> - -<h4><a name="STC_noweave"></a><code>Microweave</code>, -<code>noWeave</code> and <code>OutputCode=deltarow</code></h4> - -<p> -The first are two booleans, which implies that four combinations are -possible. Actually only three exist (if you don't count for -<code>deltarow</code>): <code>Softweave</code>, -<code>Microweave</code>, and <code>noWeave</code>. The first and -second are functionally identical, the difference being whether the driver -or the printer does the job.</p> - -<p> -In the default <code>Softweave</code> mode the driver sends the data -properly arranged to the printer, while in <code>Microweave</code> mode, -it is the printer that arranges the data. But in general the host processor -is much faster than the printer's processor, and thus it is faster for the -host do the job. In addition to that, for 720dpi eight passes are -required, and the amount of buffer space needed to buffer the data for the -passes is far beyond the printer's memory. <code>Softweave</code> -requires an odd value of "<code>escp_Band</code>"; the Stylus Color -provides fifteen for that.</p> - -<p> -"<code>OutputCode</code>" controls the encoding used. In the basic -modes, the choice consists of "plain" and "runlength". The computation of -runlength-encoded data does not take much time, less than the data tranfer -to the printer; thus this is the recommended mode, and of course the -default. With the Stylus Color, Epson introduced some new encoding -principles, namely "tiff" and "deltarow". While the first was omitted from -this driver for lack of apparent advantages, "<code>deltarow</code>" is -available as an option. "<code>Softweave</code>" cannot be used with -this encoding, so if <code>OutputCode=deltarow</code> is set, -<code>Microweave</code> becomes the default. Maybe that the size of the -ESC/P2 code becomes smaller, but I have never observed faster printing -speed. Things tend to become slower with <code>deltarow</code> compared -to <code>Softweave</code>.</p> - -<h4><a name="STC_model"></a><code>Model</code></h4> - -<p> -Some ESC/P2 printers such as the Stylus 800 do not offer -<code>Microweave</code> or the commands required to do -<code>Softweave</code>. Setting <code>Model</code> just changes the -defaults and omits some parts of the initialization sequence which are not -compatible with the given printer model. Currently only -"<code>st800</code>" is supported besides the default -<code>stcolor</code>.</p> - -<h3><a name="STC_Pitfalls"></a>Bugs and pitfalls</h3> - -<ul> -<li>The given <code>?coding</code> and <code>?transfer</code> arrays -should be strictly monotonic.</li> - -<li>It is impossible to change <code>WHITE</code>: that's your paper. -Thus RGB transfer should end at 1.0 and CMYK transfer should start at 0.0.</li> - -<li>Usually 8 bits per component yields fastest operation.</li> - -<li>The <code>ColorAdjustMatrix</code> is not used in the reverse -transformation used when Ghostscript does the dithering -(<code>gs</code>* modes). Expect funny results.</li> - -<li>If <code>BitsPerPixel</code> is less than 6, the entire coding and -transfer process does not work. This is always true for the -<code>gs</code>* modes and becomes true for the other modes if -<code>BitsPerPixel</code> is forced to low values.</li> - -<li>720×720dpi printing should never select the <code>gs</code>* -modes and should always use <code>stcolor.ps</code>. (I prefer -360×720.)</li> -</ul> - -<h3><a name="STC_Tests"></a>Tests</h3> - -<p> -This section gives an overview of performance in terms of processing and -printing times, from tests run after version 1.13. Printing was done -offline (simply copying a processed file to the printer) to measure real -printing speed without regard to speed of processing on the host, since at -high resolutions, processing time is the same order of magnitude and thus -may become the limiting factor.</p> - -<h4><a name="STC_OutputCodes"></a>The various OutputCodes</h4> - -<p> -I ran several files though Ghostscript and recorded the size of the -resulting print code, the processing time, and the printing time, at least -for some of the files, always using these options:</p> - -<blockquote><code> -gs -sDEVICE=stcolor -sPAPERSIZE=a4 stcolor.ps - < file.ps -</code></blockquote> - -<p> -(Actually "<code>-sPAPERSIZE=a4</code>" is in my -<code>gs_init.ps</code> since I'm a germ.)</p> - -<p>"<code>deltarow</code>" is the new encoding principle -("<code>ESC . 3 10 10 1</code>") with -<code>Microweave</code> on. It is activated with -"<code>-sOutputCode=deltarow</code>".</p> - -<p>"<code>Softweave</code>" actually means that nothing else was used: -it is the default, and implies that odd v=40/h=10/m=15 mode -("<code>ESC . 1 40 10 15</code>").</p> - -<p>"<code>Microweave</code>" means "<code>-dMicroweave</code>", -equivalent to "<code>ESC . 1 10 10 1</code>", -with full skip optimization and microweave activated.</p> -<p> Finally I wanted to see the plain Kathy Ireland, and used - "<code>-sOutputCode=plain</code>", which just replaces runlength - encoding (RLE) by no encoding, thus using - "<code>ESC . 0 40 10 15</code>". [So sorry <code>;-)</code> Kathy was still dressed in blue in front of the blue - sea on a blue air cushion – nice to see but hard to dither.]</p> -<p> -So here are the results.</p> - -<blockquote> -<table> -<tr> - <th colspan="5">File sizes and printing speeds with various weaving methods</th> -</tr> -<tr> - <td> </td> - <td><code>golfer.ps</code></td> - <td><code>colorcir.ps</code></td> - <td><code>drawing.ps</code></td> - <td><code>brief.ps</code></td> -</tr> -<tr> - <td><code>deltarow</code></td> - <td>572751/48.180u</td> - <td>643374/41.690u</td> - <td>90142/46.180u/1:50</td> - <td>178563/49.350u/2:22</td> -</tr> -<tr> - <td><code>Softweave</code></td> - <td>559593/46.810u</td> - <td>669966/44.960u</td> - <td>296168/48.160u/1:30</td> - <td>269808/43.320u/1:55</td> -</tr> -<tr> - <td><code>Microweave</code></td> - <td>590999/56.060u</td> - <td>754276/42.890u</td> - <td>338885/47.060u/1:50</td> - <td>282314/44.690u/2:22</td> -</tr> -</table> -</blockquote> - -<blockquote> -<table> -<tr> - <th colspan="2">Kathy Ireland</th> -</tr> -<tr> - <td></td> - <td><code>kathy.ps</code></td> -</tr> -<tr> - <td><code>deltarow</code></td> - <td>3975334/111.940u/5:35</td> -</tr> -<tr> - <td><code>Softweave</code></td> - <td>3897112/101.940u/3:10</td> -</tr> -<tr> - <td><code>Microweave</code></td> - <td>4062829/100.990u/3:15</td> -</tr> -<tr> - <td><code>plain/soft</code></td> - <td>5072255/104.390u/3:05</td> -</tr> -</table> -</blockquote> - -<p> -It may be that I've not chosen the optimal <code>deltarow</code> code, -but even if it saves at lot of bytes, printing-speed is not increased.</p> - -<p> -At least the printer prefers plain Kathy. In other words, sending 1 -Megabyte or 20% more data has no impact on printing speed. -<code>drawing.ps</code> is an exception to this rule: plain prints -slower than RLE.</p> - -<p> -"Unclever" coding -- especially with <code>deltarow</code> -- can -significantly slow down printing. But even if very significant advantages -in the size of the code are achieved, "<code>deltarow</code>" is not -competitive. <code>colorcir.ps</code> shows savings with -<code>deltarow</code>, but printing is a mess.</p> - -<h4><a name="STC_printing_time"></a>Printing time related to other options</h4> - -<p> -Full page halftone images printed, unless otherwise noted.</p> - -<blockquote> -<table> -<tr> - <th colspan="6">Printing time related to other options</th> -</tr> -<tr> - <th align="right">dpi</th> - <th align="right">Print mode</th> - <th align="right">Size KB</th> - <th align="right">Time</th> - <th colspan="2" align="left">Comments</th> -</tr> -<tr> - <td align="right">180x180 mono</td> - <td align="right">-/uni</td> - <td align="right">358</td> - <td align="right">1:15</td> - <td colspan="2"> </td> -</tr> -<tr> - <td> </td> - <td align="right">-/bi</td> - <td align="right">358</td> - <td align="right">0:45</td> - <td colspan="2"> </td> -</tr> -<tr> - <td> </td> - <td align="right">micro/bi</td> - <td align="right">205</td> - <td align="right">0:45</td> - <td colspan="2">Not Weaving</td> -</tr> -<tr> - <td> </td> - <td align="right">soft/bi</td> - <td align="right">179</td> - <td align="right">1:25</td> - <td colspan="2"> </td> -</tr> -<tr> - <td align="right">color</td> - <td align="right">-/bi</td> - <td align="right">641</td> - <td align="right">2:45</td> - <td colspan="2"> </td> -</tr> -<tr> - <td> </td> - <td align="right">soft/bi</td> - <td align="right">556</td> - <td align="right">1:32</td> - <td colspan="2"> </td> -</tr> -<tr> - <td align="right">360x360 mono</td> - <td align="right">-/uni</td> - <td align="right">269</td> - <td align="right">0:50</td> - <td colspan="2">Monochrome text</td> -</tr> -<tr> - <td> </td> - <td align="right">-/bi</td> - <td align="right">269</td> - <td align="right">0:35</td> - <td colspan="2">Monochrome text</td> -</tr> -<tr> - <td> </td> - <td align="right">micro/bi</td> - <td align="right">269</td> - <td align="right">2:25</td> - <td colspan="2">Monochrome text</td> -</tr> -<tr> - <td> </td> - <td align="right">soft/uni</td> - <td align="right">250</td> - <td align="right">3:15</td> - <td colspan="2">Monochrome text</td> -</tr> -<tr> - <td> </td> - <td align="right">soft/bi</td> - <td align="right">250</td> - <td align="right">1:55</td> - <td colspan="2">Monochrome text</td> -</tr> -<tr> - <td align="right">color</td> - <td align="right">-/bi</td> - <td align="right">346</td> - <td align="right">1:00</td> - <td colspan="2">Sparse-color page, visible displacements</td> -</tr> -<tr> - <td> </td> - <td align="right">micro/bi</td> - <td align="right">346</td> - <td align="right">1:50</td> - <td colspan="2">Sparse-color page, looks buggy – printer?</td> -</tr> -<tr> - <td> </td> - <td align="right">soft/bi</td> - <td align="right">294</td> - <td align="right">1:30</td> - <td colspan="2">Sparse-color page, O.K.</td> -</tr> -<tr> - <td> </td> - <td align="right">-/bi</td> - <td align="right">2218</td> - <td align="right">2:45</td> - <td colspan="2">Visible stripes</td> -</tr> -<tr> - <td> </td> - <td align="right">micro/bi</td> - <td align="right">5171</td> - <td align="right">3:17</td> - <td colspan="2"> </td> -</tr> -<tr> - <td> </td> - <td align="right">soft/bi</td> - <td align="right">3675</td> - <td align="right">3:05</td> - <td colspan="2"> </td> -</tr> -<tr> - <td align="right">360x720 mono</td> - <td align="right">soft/bi</td> - <td align="right">2761</td> - <td align="right">5:40</td> - <td colspan="2"> </td> -</tr> -<tr> - <td align="right">color</td> - <td align="right">soft/bi</td> - <td align="right">7789</td> - <td align="right">6:15</td> - <td colspan="2">Just a small difference!</td> -</tr> -<tr> - <td align="right">720x360 color</td> - <td align="right">soft/bi</td> - <td align="right">7182</td> - <td align="right">5:40</td> - <td colspan="2"> </td> -</tr> -<tr> - <td align="right">720x720 color</td> - <td align="right">micro/bi</td> - <td align="right">14748</td> - <td align="right">30:26</td> - <td colspan="2">Actually beyond printer's capabilities</td> -</tr> -<tr> - <td> </td> - <td align="right">soft/bi</td> - <td align="right">14407</td> - <td align="right">11:08</td> - <td colspan="2"> </td> -</tr> -</table> -</blockquote> - -<h3><a name="STC_acks"></a>Acknowledgments</h3> - -<p> -This driver was copied from <code>gdevcdj.c</code> (Ghostscript 3.12), -which was contributed by George Cameron, Koert Zeilstra, and Eckhard -Rueggeberg. Some of the ESC/P2 code was drawn from Richard Brown's -<code>gdevescp.c</code>. The POSIX interrupt code (compilation option -<code>-DSTC_SIGNAL</code>) is from Frederic Loyer. Several improvements -are based on discussions with Brian Converse, Bill Davidson, Gero Guenther, -Jason Patterson, ? Rueschstroer, and Steven Singer.</p> - -<p> -While I wish to thank everyone mentioned above, they are by no means -responsible for bugs in the stcolor driver -- just for the features.</p> - -<address> -Gunther Hess<br> -Richard Wagner Strasse 112<br> -D-47057 Duisburg<br> -Germany<br> -+49 203 376273 telephone (MET evening hours)<br> -<<a href="mailto:ghess@elmos.de">ghess@elmos.de</a>> -</address> - -<hr> - -<h2><a name="Uniprint"></a>uniprint, a flexible unified printer driver</h2> - -<p> -<code>uniprint</code> is a unified parametric driver by Gunther Hess -<<a href="mailto:ghess@elmos.de">ghess@elmos.de</a>> for several -kinds of printers and devices, including</p> - -<blockquote> -<ul> -<li>any Epson Stylus Color, Stylus, or Stylus Pro</li> -<li>HP PCL/RTL</li> -<li>Canon BubbleJet Color 610</li> -<li>NEC P2X</li> -<li>Sun raster file format</li> -</ul></blockquote> - -<p> -This driver is intended to <em>become</em> a unified printer driver. If you -consider it ugly, please send me your suggestions for improvements. The -driver will be updated with them. Thus the full explanation of the driver's -name is:</p> - -<blockquote> -Ugly- -> Updated- -> Unified Printer Driver -</blockquote> - -<p> -But you probably want to know something about the functionality. -At the time of this writing uniprint drives:</p> - -<ul> -<li>NEC Pinwriter P2X (24-pin monochrome impact printer, ESC/P style)</li> -<li>Several Epson Stylus Color models (ESC/P2 style)</li> -<li>HP-DeskJet 550c (basic HP-RTL)</li> -<li>Canon BJC 610</li> -</ul> - -<p> -It can be configured for various other printers without recompilation -and offers uncompressed (ugly) Sun rasterfiles as another format, but -this format is intended for testing purposes rather than real use. -The usage of this driver is quite simple. The typical command line looks -like this:</p> - -<blockquote> -<code>gs @</code>{MODEL}<code>.upp -sOutputFile=</code>{printable file}<code> MyFile.ps -c quit</code> -</blockquote> - -<p> -For example, from my Linux box:</p> - -<blockquote><code> -gs @stc.upp -sOutputFile=/dev/lp1 tiger.eps -c quit -</code></blockquote> - -<blockquote> -<table> -<tr> - <th colspan="3">Unified Printer Parameter files distributed with Ghostscript</th> -</tr> -<tr> - <th align="left" colspan="3">Canon BJC 610 (color, rendered)</th> -</tr> -<tr> - - <td><code>bjc610a0.upp</code></td> - - <td>360×360dpi</td> - - <td>plain paper, high speed</td> -</tr> -<tr> - - <td><code>bjc610a1.upp</code></td> - - <td>360×360dpi</td> - - <td>plain paper</td> -</tr> -<tr> - - <td><code>bjc610a2.upp</code></td> - - <td>360×360dpi</td> - - <td>coated paper</td> -</tr> -<tr> - - <td><code>bjc610a3.upp</code></td> - - <td>360×360dpi</td> - - <td>transparency film</td> -</tr> -<tr> - - <td><code>bjc610a4.upp</code></td> - - <td>360×360dpi</td> - - <td>back print film</td> -</tr> -<tr> - - <td><code>bjc610a5.upp</code></td> - - <td>360×360dpi</td> - - <td>fabric sheet</td> -</tr> -<tr> - - <td><code>bjc610a6.upp</code></td> - - <td>360×360dpi</td> - - <td>glossy paper</td> -</tr> -<tr> - - <td><code>bjc610a7.upp</code></td> - - <td>360×360dpi</td> - - <td>high gloss film</td> -</tr> -<tr> - - <td><code>bjc610a8.upp</code></td> - - <td>360×360dpi</td> - - <td>high resolution paper</td> -</tr> -<tr> - <th colspan="3"></th> -</tr> -<tr> - - <td><code>bjc610b1.upp</code></td> - - <td>720×720dpi</td> - - <td>plain paper</td> -</tr> -<tr> - - <td><code>bjc610b2.upp</code></td> - - <td>720×720dpi</td> - - <td>coated paper</td> -</tr> -<tr> - - <td><code>bjc610b3.upp</code></td> - - <td>720×720dpi</td> - - <td>transparency film</td> -</tr> -<tr> - - <td><code>bjc610b4.upp</code></td> - - <td>720×720dpi</td> - - <td>back print film</td> -</tr> -<tr> - - <td><code>bjc610b6.upp</code></td> - - <td>720×720dpi</td> - - <td>glossy paper</td> -</tr> -<tr> - - <td><code>bjc610b7.upp</code></td> - - <td>720×720dpi</td> - - <td>high-gloss paper</td> -</tr> -<tr> - - <td><code>bjc610b8.upp</code></td> - - <td>720×720dpi</td> - - <td>high resolution paper</td> -</tr> -<tr> - <th align="left" colspan="3">HP Ink-Printers</th> -</tr> -<tr> - - <td><code>cdj550.upp</code></td> - - <td>300×300dpi</td> - - <td>32-bit CMYK</td> -</tr> -<tr> - - <td><code>cdj690.upp</code></td> - - <td>300×300dpi</td> - - <td>Normal mode</td> -</tr> -<tr> - - <td><code>cdj690ec.upp</code></td> - - <td>300×300dpi</td> - - <td>Economy mode</td> -</tr> -<tr> - - <td><code>dnj750c.upp</code></td> - - <td>300×300dpi</td> - - <td>Color – also good for 450C</td> -</tr> -<tr> - - <td><code>dnj750m.upp</code></td> - - <td>600×600dpi</td> - - <td>Monochrome</td> -</tr> -<tr> - <th align="left" colspan="3">NEC P2X</th> -</tr> -<tr> - - <td><code>necp2x.upp</code></td> - - <td>360×360dpi</td> - - <td>8-bit (Floyd-Steinberg)</td> -</tr> -<tr> - <th align="left" colspan="3">Any Epson Stylus Color</th> -</tr> -<tr> - - <td><code>stcany.upp</code></td> - - <td>360×360dpi</td> - - <td>4-bit, PostScript halftoning</td> -</tr> -<tr> - - <td><code>stcany_h.upp</code></td> - - <td>720×720dpi</td> - - <td>4-bit, PostScript halftoning</td> - </tr> -<tr> - <th align="left" colspan="3">Original Epson Stylus and Stylus Pro Color</th> - </tr> -<tr> - - <td><code>stc.upp</code></td> - - <td>360×360dpi</td> - - <td>32-bit CMYK, 15-pin</td> - </tr> -<tr> - - <td><code>stc_l.upp</code></td> - - <td>360×360dpi</td> - - <td>4-bit, PostScript halftoning, weaved noWeave</td> - </tr> -<tr> - - <td><code>stc_h.upp</code></td> - - <td>720×720dpi</td> - - <td>32-bit CMYK, 15-pin Weave</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color II</th> - </tr> -<tr> - - <td><code>stc2.upp</code></td> - - <td>360×360dpi</td> - - <td>32-bit CMYK, 20-pin, Epson Stylus Color II(s)</td> - </tr> -<tr> - - <td><code>stc2_h.upp</code></td> - - <td>720×720dpi</td> - - <td>32-bit CMYK, 20-pin, Epson Stylus Color II</td> - </tr> -<tr> - - <td><code>stc2s_h.upp</code></td> - - <td>720×720dpi</td> - - <td>32-bit CMYK, 20-pin, Epson Stylus Color IIs</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color 200</th> - </tr> -<tr> - - <td><code>stc200.upp</code></td> - - <td>360×720dpi</td> - - <td>Plain Paper</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color 300</th> - </tr> -<tr> - - <td><code>stc300.upp</code></td> - - <td>360×360dpi</td> - - <td>32-bit CMYK, plain paper</td> - </tr> -<tr> - - <td><code>stc300bl.upp</code></td> - - <td>180×180dpi</td> - - <td>black only, plain paper</td> - </tr> -<tr> - - <td><code>stc300bm.upp</code></td> - - <td>360×360dpi</td> - - <td>black only, plain paper</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color 500 (good transfer curves for plain paper)</th> - </tr> -<tr> - - <td><code>stc500p.upp</code></td> - - <td>360×360dpi</td> - - <td>32-bit CMYK, noWeave, plain paper</td> - </tr> -<tr> - - <td><code>stc500ph.upp</code></td> - - <td>720×720dpi</td> - - <td>32-bit CMYK, noWeave, plain paper</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color 600, 32/90-inch weaving</th> - </tr> -<tr> - - <td><code>stc600pl.upp</code></td> - - <td>360×360dpi</td> - - <td>32-bit CMYK, 32-pin, plain paper</td> - </tr> -<tr> - - <td><code>stc600p.upp</code></td> - - <td>720×720dpi</td> - - <td>32-bit CMYK, 32-pin, plain paper</td> - </tr> -<tr> - - <td><code>stc600ih.upp</code></td> - - <td>1440×720dpi</td> - - <td>32-bit CMYK, 30-pin, inkjet paper</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color 640</th> - </tr> -<tr> - - <td><code>stc640p.upp</code></td> - - <td>720×720dpi</td> - - <td>plain paper?</td> - </tr> -<tr> - - <td><code>st640p.upp</code></td> - - <td>720×720dpi</td> - - <td>CMYK, plain paper</td> - </tr> -<tr> - - <td><code>st640pg.upp</code></td> - - <td>720×720dpi</td> - - <td>grayscale, plain paper</td> - </tr> -<tr> - - <td><code>st640pl.upp</code></td> - - <td>360×360dpi</td> - - <td>CMYK, plain paper</td> - </tr> -<tr> - - <td><code>st640plg.upp</code></td> - - <td>360×360dpi</td> - - <td>grayscale, plain paper</td> - </tr> -<tr> - - <td><code>st640ih.upp</code></td> - - <td>1440×720dpi</td> - - <td>CMYK, inkjet paper</td> - </tr> -<tr> - - <td><code>st640ihg.upp</code></td> - - <td>1440×720dpi</td> - - <td>grayscale, inkjet paper</td> - </tr> -<tr> - <th align="left" colspan="3">Epson Stylus Color 800, 64/180-inch weaving</th> - </tr> -<tr> - - <td><code>stc800pl.upp</code></td> - - <td>360×360dpi</td> - - <td>32-bit CMYK, 64-pin, plain paper</td> - </tr> -<tr> - - <td><code>stc800p.upp</code></td> - - <td>720×720dpi</td> - - <td>32-bit CMYK, 64-pin, plain paper</td> - </tr> -<tr> - - <td><code>stc800ih.upp</code></td> - - <td>1440×720dpi</td> - - <td>32-bit CMYK, 62-pin, inkjet paper</td> - </tr> -<tr> - - <td><code>stc1520.upp</code></td> - - <td>1440×720dpi</td> - - <td>32-bit CMYK, 62-pin, inkjet paper</td> - </tr> -<tr> - <th align="left" colspan="3">Sun raster file</th> - </tr> -<tr> - - <td><code>ras1.upp</code></td> - - <td>1-bit</td> - - <td>monochrome (Ghostscript)</td> - </tr> -<tr> - - <td><code>ras3.upp</code></td> - - <td>3-bit</td> - - <td>RGB (Ghostscript)</td> - </tr> -<tr> - - <td><code>ras4.upp</code></td> - - <td>4-bit</td> - - <td>CMYK (Ghostscript)</td> - </tr> -<tr> - - <td><code>ras8m.upp</code></td> - - <td>8-bit</td> - - <td>grayscale (Floyd-Steinberg)</td> - </tr> -<tr> - - <td><code>ras24.upp</code></td> - - <td>24-bit</td> - - <td>RGB (Floyd-Steinberg)</td> - </tr> -<tr> - - <td><code>ras32.upp</code></td> - - <td>32-bit</td> - - <td>CMYK (CMYK-Floyd-Steinberg)</td> -</tr> -</table> -</blockquote> - -<p> -Thanks to Danilo Beuche, Guido Classen, Mark Goldberg and Hans-Heinrich -Viehmann for providing the files for the stc200, hp690, stc500 and the -stc640. Thanks to Michael Lossin <losse@germanymail.com> for the -newer st640 parameter sets.</p> - -<p> -Please note the following:</p> - -<blockquote><ul> -<li>Changing the resolution with Ghostscript's -<a href="Use.htm#Resolution_switch"><code>-r</code> switch</a> is -usually not possible.</li> -<li>For Epson Stylus Color models not listed above, the two -<code>stc500</code> variants are likely to work in addition to -<code>stcany</code>, but their gamma correction might be wrong.</li> -</ul></blockquote> - -<h3><a name="Uni_state"></a>The state of this driver</h3> - -<p> -The coding of <code>uniprint</code> was triggered by the requirements of -the various Stylus Color models and some personal needs for HP and NEC -drivers. Thus the Epson models are well represented among the distributed -parameter files. When this driver entered the beta test phase, three other -drivers appreared on the scene that could be at least partially integrated -into <code>uniprint</code>: <code>cdj850</code> by Uli Wortmann -(available at <a href="http://www.erdw.ethz.ch/~bonk/hp850/hp850.html">http://www.erdw.ethz.ch/~bonk/hp850/hp850.html</a>), -<code>hpdj</code> by Martin Lottermoser, and <code>bjc610</code> by -Helmut Riegler.</p> - -<p> -Uli addresses features of the more recent DeskJet models that will not be -available in <code>uniprint</code> soon. Martin taught me a lesson on -HP-PCL3 headers that will be available in <code>uniprint</code> -soon. Helmut in turn followed an almost similar idea, but targetted -primarily for printing on Canon printers from the pbmplus library. Starting -with version 1.68 of uniprint, BJC support is available. Work on the -<code>hpdj</code> integration will start after the update of my website.</p> - -<h3><a name="Uni_background"></a>Notes on <code>uniprint</code>'s background</h3> - -<p> -<code>uniprint</code> is actually an update of <code>stcolor</code>, -but much more versatile than its predecessor; <code>stcolor</code>, in -its turn, started as a clone of the color DeskJet family of drivers -(<code>cdj</code>*). Finally, <code>cdj</code>* can be considered an -addition of features to the simpler monochrome drivers of Ghostscript. This -addition of features is useful to get an idea of the functionality of -<code>uniprint</code>:</p> - -<blockquote> -<dl> -<dt>Monochrome to advanced color (<code>cdj</code>*): -<dd>This adds color mapping and rendering functions to the driver. -Error diffusion is especially important for the quality of printing. -</dl> - -<dl> -<dt>HP color to Epson Color (<code>stcolor</code>) -<dd>The Epson Stylus Color offered two features simultaneously: it could -produce 720×720dpi output and it could soak the paper. In other -words, it required more color management features inside the driver. This -is still the major conceptual difference in the data generation for HP and -Epson printers. -</dl> - -<dl> -<dt>Weaving techniques (<code>stcolor</code>) -<dd>Besides the internal color management, the Stylus Color did not provide -enough buffer space to operate the printer fast at 720×720dpi. The -use of weaving could yield triple the print speed. Weaving, also called -interleaving, is present in some monochrome drivers too. The new thing in -<code>stcolor</code> was the combination with error diffusion. -Unfortunately the weaving was somehow hard-coded, as the problems with the -newer members of the Stylus Color family of printers demonstrated. -</dl> - -<dl> -<dt>Generalized output format and weaving (<code>uniprint</code>) -<dd>The features mentioned above yield about 90% of -<code>stcolor</code>'s source code; only 10% is related to the -formatting of the output. The idea to make the output format switchable -came up soon after completing <code>stcolor</code>, but its final design -was triggered by the (personal) necessity to drive a NEC P2X and a -Designjet 750c. -</dl></blockquote> - -<p> -Thus <code>uniprint</code> accumulates almost any features that can be -found among the other printer drivers, which clearly has some disadvantage -in processing speed -- true in particular of version 1.75, since it was -targetted for functionality, and several speed-gaining features were -(knowingly) omitted.</p> - -<p> -To summarize and to introduce the terms used in the description of the -parameters, the features of <code>uniprint</code> that can be -parameterized are:</p> - -<blockquote><ul> -<li>color mapping,</li> -<li>color rendering (error diffusion or Floyd-Steinberg),</li> -<li>output format, including</li> -<li>weaving.</li> -</ul></blockquote> - -<h3><a name="Uni_make_pfile"></a>Godzilla's guide to the creation of Unified Printer Parameter (<code>.upp</code>) files</h3> - -<p> -Here is one of the distributed parameter files (<code>stc_l.upp</code>) -with some added comments. Also see the section that describes -<a href="#Uni_all_parameters">all <code>uniprint</code>'s parameters in -brief</a>.</p> - -<pre> --supModel="Epson Stylus Color I (and PRO Series), 360x360DpI, noWeave" --sDEVICE=uniprint -- Select the driver --dNOPAUSE -- Useful with printers --dSAFER -- Provides some security --dupColorModel=/DeviceCMYK -- Selects the color mapping --dupRendering=/ErrorDiffusion -- Selects the color rendering --dupOutputFormat=/EscP2 -- Selects the output format --r360x360 -- Adjusts the resolution --dupMargins="{ 9.0 39.96 9.0 9.0}" -- Establishes (L/B/R/T margins in points) --dupComponentBits="{1 1 1 1}" -- Map: bits per component (default: 8) --dupWeaveYPasses=4 -- Weave: Y-passes (default: 1) --dupOutputPins=15 -- Format/weave: scans per Command --dupBeginPageCommand="< -- Goes to the printer - 1b40 1b40 -- ESC '@' ESC '@' -> dual reset - 1b2847 0100 01 -- ESC '(' 'G' 1 0 1 -> graphics - 1b2869 0100 00 -- ESC '(' 'i' 1 0 1 -> no HW weave - 1b2855 0100 0A -- ESC '(' 'U' 1 0 10 -> 360dpi - 1b5500 -- ESC 'U' 0 -> bidir print - 1b2843 0200 0000 -- ESC '(' 'C' 2 0 xx -> page length - 1b2863 0400 0000 0000 -- ESC '(' 'c' 4 0 xxxx -> margins ->" -- as it is, unless: --dupAdjustPageLengthCommand -- Adjust page length in BOP requested --dupAdjustTopMarginCommand -- Adjust top margin in BOP --dupAdjustBottomMarginCommand -- Adjust bottom margin in BOP --dupEndPageCommand="(\033@\014)" -- Last (but one) data to the printer --dupAbortCommand="(\033@\15\12\12\12\12 Printout-Aborted\15\014)" -</pre> - -<p> -That's short, and if one removes <code>upWeaveYPasses</code> and -<code>upOutputPins</code> it becomes shorter, almost -<code>stcany.upp</code>. This miniature size is because I am most -familiar with ESC/P2, and was able to add defaults for the omitted -parameters. Now a few notes about the parameters used in this example:</p> - -<ul> -<li><code>upModel</code> is a string serving as a comment (and nothing else).</li> - -<li><a href="Use.htm#Output_device"><code>DEVICE</code></a>, -<a href="Use.htm#NoPause"><code>NOPAUSE</code></a>, <a -href="Use.htm#Safer"><code>SAFER</code></a> are well-known Ghostscript -parameters described in the <a href="Use.htm">usage documentation</a>.</li> - -<li><code>upColorModel</code> is one of major <code>uniprint</code> -parameters: it selects the color mapping and in turn the PostScript color -model. It supports the devices <code>/DeviceGray</code>, <code>/DeviceRGBW</code>, <code>/DeviceRGB</code>, <code>/DeviceCMYK</code>, and <code>/DeviceCMYKgenerate</code>.</li> - -<li><code>upRendering</code> selects the (color) rendering, supporting -the values <code>/ErrorDiffusion</code> and <code>/FSCMYK32</code>. -<code>/ErrorDiffusion</code> is similar to <code>fsmono</code>, -<code>fsrgb</code> and <code>fsx4</code> of <code>stcolor</code>, -while <code>/FSCMYK32</code> is (almost) identical to -<code>fscmyk</code> and <code>hscmyk</code>, but is restricted to -32-bit data and should be used in conjunction with -<code>/DeviceCMYKgenerate</code>.</li> - -<li><code>upOutputFormat</code> selects the output method, supporting the values -<code>/SunRaster</code>, <code>/Epson</code>, <code>/EscP2</code>, <code>/EscP2XY</code>, and<code>/Pcl</code>. - -<blockquote> -<table> -<tr> - <td><code>/SunRaster</code></td> - - <td>creates Sun raster files and requires no other parameters</td> - </tr> -<tr> - <td><code>/Epson</code></td> - - <td>is used for the elderly ESC/P format (used by many printers)</td> - </tr> -<tr> - <td><code>/EscP2</code></td> - - <td>is used by more recent Epson printers (no X weaving supported)</td> - </tr> -<tr> - <td><code>/EscP2XY</code></td> - - <td>supports X-Weaving, used with 1440dpi printers and in <code>stc2s_h</code></td> - </tr> -<tr> - <td><code>/Pcl</code></td> - - <td>HP PCL/RTL-style output formatter without weaving</td> - </tr> -</table> -</blockquote> -</li> -<li><code>-r360x360</code> is Ghostscript's standard -<a href="Use.htm#Resolution_switch">resolution switch</a>.</li> - -<li><code>upMargins="{ 9.0 39.96 9.0 9.0}"</code> -has function similar to the Ghostscript parameter -<code>.HWMargins</code>: it sets the left, bottom, right, and top -margins in points. <code>uniprint</code> provides this parameter to -enable automatic left-right exchange if <code>upYFlip</code> is active.</li> - -<li><code>upComponentBits</code> is an array of integers that selects -the bits stored in raster memory, by default 8 bits per component. In this -example, 1 bit is selected for each component, thus turning down the -Floyd-Steinberg algorithm (but still carrying out the time-consuming -computation). The related parameter "<code>upComponentShift</code>" -controls positioning the components within raster memory. Each of the -numbers given corresponds to a component which depends on the selected -"<code>upColorModel</code>": -<blockquote> -<table> -<tr> - <td align="center"> </td> - - <td align="center"><code>/DeviceGray</code></td> - - <td align="center"><code>/DeviceRGBW</code></td> - - <td align="center"><code>/DeviceRGB</code></td> - - <td align="center"><code>/DeviceCMYK</code></td> - - <td align="center"><code>/DeviceCMYKgenerate</code></td> - </tr> -<tr> - <td colspan="6"></td> - </tr> -<tr> - <td align="center">0</td> - - <td align="center">White</td> - - <td align="center">White</td> - - <td align="center">Red</td> - - <td align="center">Black</td> - - <td align="center">Black</td> - </tr> -<tr> - <td align="center">1</td> - - <td align="center">--</td> - - <td align="center">Red</td> - - <td align="center">Green</td> - - <td align="center">Cyan</td> - - <td align="center">Cyan</td> - </tr> -<tr> - <td align="center">2</td> - - <td align="center">--</td> - - <td align="center">Green</td> - - <td align="center">Blue</td> - - <td align="center">Magenta</td> - - <td align="center">Magenta</td> - </tr> -<tr> - <td align="center">3</td> - - <td align="center">--</td> - - <td align="center">Blue</td> - - <td align="center">--</td> - - <td align="center">Yellow</td> - - <td align="center">Yellow</td> - </tr> -</table> - -<p> -This order may not be suitable for some printers, so another parameter -"<code>upOutputComponentOrder</code>", also an array of integers, -selects the output order using the numbers on the left.</p> -</blockquote> - -<p> -One group of very important parameters not used in the example above -deserves to be mentioned here: the transfer arrays, named -"<code>up<em>{color}</em>Transfer</code>", where -<code><em>{color}</em></code> is one of the names in the table above. -These are -arrays of floats in the range 0.0 - 1.0 representing the color transfer -functions. They are used during mapping and rendering. In the simplest -case, these arrays ensure an equidistant distribution of the stored values -within the device space (which means a nonlinear mapping from Ghostscript's -point of view). If the given array does not cover the entire range from 0 -to 1, which applies for the Stylus Color family at high resolution for some -media, only the relevant part gets mapped to raster memory (meaning that -is's fully utilized) and the rendering takes care of the "overhang" (in -this case the post-diffusion of 1-bit components makes sense).</p> - -<p> -Finally an important note on the transfer arrays: for monochrome devices -the stored component is <code>White</code>, which is the way PostScript -defines these devices, but most printers require <code>Black</code>. -Thus one has to provide a falling "<code>upWhiteTransfer</code>" for -such printers.</p> -</li> - -<li><code>upWeaveYPasses</code> is an integer that gives the number of -print head passes required to achieve the requested Ydpi. This makes sense -only if</li> - -<li><code>upOutputPins</code> is set to something greater than 1. Thus -multiple pins or nozzles are transferred with a single command, and of -course such a command must be supported by the device.</li> - -</ul> - -<p> -If no other weave parameters are given, <code>uniprint</code> computes -several defaults which together do no weaving. The <code>/Epson</code> -and <code>/EscP2XY</code> formats take care of -"<code>upWeaveXPasses</code>" too.</p> - -<ul> - -<li><code>upBeginPageCommand</code> represents the data transferred to -the printer whenever a new page begins. Before that, -"<code>upBeginJobCommand</code>" is written to the device only once per -output file. (Intended for the HP PJL sequences).</li> - -<li><code>upAdjustBottomMarginCommand</code>, -<code>upAdjustMediaSize</code>, -<code>upAdjustPageLengthCommand</code>, -<code>upAdjustPageWidthCommand</code>, -<code>upAdjustResolutionCommand</code>, and -<code>upAdjustTopMarginCommand</code> - -<p> -Normally <code>uniprint</code> does not change the -"<code>upBeginPageCommand</code>", nor does it provide a default. -However, if the above boolean values are set, the corresponding values are -changed (provided that the code of the formatters supports this change and -the commands to be adjusted are included in the BOP string).</p> -</li> - -<li><code>upEndPageCommand</code> is the fixed termination sequence for -each page, and of course there is an "<code>upEndJobCommand</code>" too.</li> - -<li><code>upAbortCommand</code> is written if <code>uniprint</code>'s -interrupt detection is enabled and a signal is caught. It replaces -"<code>upEndPageCommand</code>" and "<code>upEndJobCommand</code>", -thus allowing the indication of an aborted job. (Ghostscript gets an error -return from <code>uniprint</code> in this case, and abandons further -processing.)</li> - -</ul> - -<p> -For the ESC/P(2) formats all commands represent binary data, while for -the PCL/RTL formatter some of them are formats for <code>fprintf</code>. These strings -<b><em>must</em></b> explicitly have a trailing "\0'.</p> - -<p> -I should write more, but the only recommendation is to -take a look at the various parameter files. Here are a few more hints.</p> - -<ul> -<li>If the Driver rejects a configuration, nothing happens until -<code>showpage</code>; then an error is raised and a message with -"CALL-REJECTED upd_print_page..." is printed on stderr.</li> - -<li><code>uniprint</code> has lots of messages that can be activated by -setting bits in the preprocessor macro <code>UPD_MESSAGES</code>. I -usually use the compile-time option <code>-DUPD_MESSAGES=0x17</code> for -configuration development. (For the semantics, check the -<code>UPD_M_</code> macros in the source.)</li> - -<li>A program "<code>uninfo.ps</code>" distributed with Ghostscript -displays interactively in alphabetical order the contents of the current -pagedevice dictionary. This includes any parameters generated or changed by -<code>uniprint</code>.</li> -</ul> - -<h3><a name="Uni_all_parameters"></a>All parameters in brief</h3> - -<p> -This table gives a brief explanation of every parameter known to -<code>uniprint</code>, listing them in alphabetical order. "[ ]" -denotes that a parameter is an array, and "(RO)" that it is read-only.</p> - -<blockquote> -<table> -<tr> - <th colspan="3">All uniprint parameters</th> - </tr> -<tr> - <th align="left">Parameter</th> - - <th align="left">Type</th> - - <th align="left">Use</th> - </tr> -<tr> - <td><code>upAbortCommand</code></td> - - <td>String</td> - - <td>End of page and file on interrupt</td> - </tr> -<tr> - <td><code>upAdjustBottomMarginCommand</code></td> - - <td>Bool</td> - - <td>Manipulate bottom margin in <code>upBeginPageCommand</code></td> - </tr> -<tr> - <td><code>upAdjustMediaSizeCommand</code></td> - - <td>Bool</td> - - <td>Manipulate <code>Mediasize</code> [intended]</td> - </tr> -<tr> - <td><code>upAdjustPageLengthCommand</code></td> - - <td>Bool</td> - - <td>Manipulate page length in <code>upBeginPageCommand</code></td> - </tr> -<tr> - <td><code>upAdjustPageWidthCommand</code></td> - - <td>Bool</td> - - <td>Manipulate page width in <code>upBeginPageCommand</code></td> - </tr> -<tr> - <td><code>upAdjustResolutionCommand</code></td> - - <td>Bool</td> - - <td>Manipulate resolution</td> - </tr> -<tr> - <td><code>upAdjustTopMarginCommand</code></td> - - <td>Bool</td> - - <td>Manipulate top margin in <code>upBeginPageCommand</code></td> - </tr> -<tr> - <td><code>upBeginJobCommand</code></td> - - <td>String</td> - - <td>Begin each output file</td> - </tr> -<tr> - <td><code>upBeginPageCommand</code></td> - - <td>String</td> - - <td>Begin each page</td> - </tr> -<tr> - <td><code>upBlackTransfer</code></td> - - <td>Float[ ]</td> - - <td>Black transfer (CMYK only!)</td> - </tr> -<tr> - <td><code>upBlueTransfer</code></td> - - <td>Float[ ]</td> - - <td>Blue transfer</td> - </tr> -<tr> - <td><code>upColorInfo</code></td> - - <td>Int[ ]</td> - - <td>struct <code>gx_device_color_info</code></td> - </tr> -<tr> - <td><code>upColorModel</code></td> - - <td>Name</td> - - <td>Select color mapping</td> - </tr> -<tr> - <td><code>upColorModelInitialized</code></td> - - <td>Bool (RO)</td> - - <td>Color mapping OK</td> - </tr> -<tr> - <td><code>upComponentBits</code></td> - - <td>Int[ ]</td> - - <td>Bits stored per component</td> - </tr> -<tr> - <td><code>upComponentShift</code></td> - - <td>Int[ ]</td> - - <td>Positioning within <code>gx_color_index</code></td> - </tr> -<tr> - <td><code>upCyanTransfer</code></td> - - <td>Float[ ]</td> - - <td>Cyan transfer</td> - </tr> -<tr> - <td><code>upEndJobCommand</code></td> - - <td>String</td> - - <td>End each file unless <code>upAbortCommand</code></td> - </tr> -<tr> - <td><code>upEndPageCommand</code></td> - - <td>String</td> - - <td>End each page unless <code>upAbortCommand</code></td> - </tr> -<tr> - <td><code>upErrorDetected</code></td> - - <td>Bool (RO)</td> - - <td>Severe (VM) error, not fully operational</td> - </tr> -<tr> - <td><code>upFSFixedDirection</code></td> - - <td>Bool</td> - - <td>Inhbits direction toggling in rendering</td> - </tr> -<tr> - <td><code>upFSProcessWhiteSpace</code></td> - - <td>Bool</td> - - <td>Causes white-space rendering</td> - </tr> -<tr> - <td><code>upFSReverseDirection</code></td> - - <td>Bool</td> - - <td>Run rendering in reverse (if fixed)</td> - </tr> -<tr> - <td><code>upFSZeroInit</code></td> - - <td>Bool</td> - - <td>Non-random rendering initialization</td> - </tr> -<tr> - <td><code>upFormatXabsolute</code></td> - - <td>Bool</td> - - <td>Write absolute X coordinates</td> - </tr> -<tr> - <td><code>upFormatYabsolute</code></td> - - <td>Bool</td> - - <td>Write absolute Y coordinates</td> - </tr> -<tr> - <td><code>upGreenTransfer</code></td> - - <td>Float[ ]</td> - - <td>Green transfer</td> - </tr> -<tr> - <td><code>upMagentaTransfer</code></td> - - <td>Float[ ]</td> - - <td>Magenta transfer</td> - </tr> -<tr> - <td><code>upMargins</code></td> - - <td>Float[ ]</td> - - <td>L/B/R/T margins in points</td> - </tr> -<tr> - <td><code>upModel</code></td> - - <td>String</td> - - <td>Comment string, holds some info</td> - </tr> -<tr> - <td><code>upOutputAborted</code></td> - - <td>Bool (RO)</td> - - <td>Caught an interrupt</td> - </tr> -<tr> - <td><code>upOutputBuffers</code></td> - - <td>Int</td> - - <td>Number of rendering buffers (2^<small><sup><b>N</b></sup></small>)</td> - </tr> -<tr> - <td><code>upOutputComponentOrder</code></td> - - <td>Int[ ]</td> - - <td>Order of components when printing</td> - </tr> -<tr> - <td><code>upOutputComponents</code></td> - - <td>Int</td> - - <td>Number of written components, not fully operational</td> -<tr> - <td><code>upOutputFormat</code></td> - - <td>Name</td> - - <td>Select output format</td> - </tr> -<tr> - <td><code>upOutputFormatInitialized</code></td> - - <td>Bool (RO)</td> - - <td>Format data OK</td> - </tr> -<tr> - <td><code>upOutputHeight</code></td> - - <td>Int</td> - - <td>Output height in pixels</td> - </tr> -<tr> - <td><code>upOutputPins</code></td> - - <td>Int</td> - - <td>Number of pins / nozzles per command</td> - </tr> -<tr> - <td><code>upOutputWidth</code></td> - - <td>Int</td> - - <td>Output width in pixels</td> - </tr> -<tr> - <td><code>upOutputXOffset</code></td> - - <td>Int</td> - - <td>Offset in pixels, if <code>upFormatXabsolute</code></td> -</tr> -<tr> - <td><code>upOutputXStep</code></td> - - <td>Int</td> - - <td>Divisor or multiplier for X coords</td> - </tr> -<tr> - <td><code>upOutputYOffset</code></td> - - <td>Int</td> - - <td>Offset in pixels, if <code>upFormatYabsolute</code></td> - </tr> -<tr> - <td><code>upOutputYStep</code></td> - - <td>Int</td> - - <td>Divisor or multiplier for Y coords</td> - </tr> -<tr> - <td><code>upRasterBufferInitialized</code></td> - - <td>Bool (RO)</td> - - <td>GS buffer OK</td> - </tr> -<tr> - <td><code>upRedTransfer</code></td> - - <td>Float[ ]</td> - - <td>Red transfer</td> -</tr> -<tr> - <td><code>upRendering</code></td> - - <td>Name</td> - - <td>Select rendering algorithm</td> - </tr> -<tr> - <td><code>upRenderingInitialized</code></td> - - <td>Bool (RO)</td> - - <td>Rendering parameters OK</td> - </tr> -<tr> - <td><code>upSelectComponentCommands</code></td> - - <td>String[ ]</td> - - <td>Establish color (output order!)</td> - </tr> -<tr> - <td><code>upSetLineFeedCommand</code></td> - - <td>String</td> - - <td>Adjust linefeed (Epson only)</td> - </tr> -<tr> - <td><code>upVersion</code></td> - - <td>String (RO)</td> - - <td>Source code version</td> - </tr> -<tr> - <td><code>upWeaveFinalPins</code></td> - - <td>Int[ ]</td> - - <td>Number of bottom pins on EOP passes</td> - </tr> -<tr> - <td><code>upWeaveFinalScan</code></td> - - <td>Int</td> - - <td>Begin EOP passes (Y-coord)</td> - </tr> -<tr> - <td><code>upWeaveFinalXStarts</code></td> - - <td>Int[ ]</td> - - <td>X-pass indices for EOP passes</td> - </tr> -<tr> - <td><code>upWeaveFinalYFeeds</code></td> - - <td>Int[ ]</td> - - <td>Y increments for EOP passes</td> - </tr> -<tr> - <td><code>upWeaveInitialPins</code></td> - - <td>Int[ ]</td> - - <td>Number of top pins on BOP passes</td> - </tr> -<tr> - <td><code>upWeaveInitialScan</code></td> - - <td>Int</td> - - <td>End BOP passes (Y coord)</td> - </tr> -<tr> - <td><code>upWeaveInitialXStarts</code></td> - - <td>Int[ ]</td> - - <td>X-pass indices for BOP passes</td> - </tr> -<tr> - <td><code>upWeaveInitialYFeeds</code></td> - - <td>int[ ]</td> - - <td>Y increments for BOP passes</td> - </tr> -<tr> - <td><code>upWeavePasses</code></td> - - <td>Int</td> - - <td>XPasses × YPasses</td> - </tr> -<tr> - <td><code>upWeaveXPasses</code></td> - - <td>Int</td> - - <td>Number of X passes</td> -</tr> -<tr> - <td><code>upWeaveXStarts</code></td> - - <td>Int[ ]</td> - - <td>X-pass indices for normal passes</td> - </tr> -<tr> - <td><code>upWeaveYFeeds</code></td> - - <td>Int[ ]</td> - - <td>Y increments for normal passes</td> - </tr> -<tr> - <td><code>upWeaveYOffset</code></td> - - <td>Int</td> - - <td>Number of blank or incomplete scans at BOP</td> - </tr> -<tr> - <td><code>upWeaveYPasses</code></td> - - <td>Int</td> - - <td>Number of X passes</td> - </tr> -<tr> - <td><code>upWhiteTransfer</code></td> - - <td>Float[ ]</td> - - <td>White transfer (monochrome devices!)</td> - </tr> -<tr> - <td><code>upWriteComponentCommands</code></td> - - <td>String[ ]</td> - - <td>Commands to write each component</td> - </tr> -<tr> - <td><code>upWroteData</code></td> - - <td>Bool (RO)</td> - - <td>Something (<code>BeginJob</code>) written to output</td> - </tr> -<tr> - <td><code>upXMoveCommand</code></td> - - <td>String</td> - - <td>X positioning command</td> - </tr> -<tr> - <td><code>upXStepCommand</code></td> - - <td>String</td> - - <td>Single step to the right</td> - </tr> -<tr> - <td><code>upYFlip</code></td> - - <td>Bool</td> - - <td>Flips output along the Y axis</td> - </tr> -<tr> - <td><code>upYMoveCommand</code></td> - - <td>String</td> - - <td>Y positioning command</td> - </tr> -<tr> - <td><code>upYStepCommand</code></td> - - <td>String</td> - - <td>Single step down</td> - </tr> -<tr> - <td><code>upYellowTransfer</code></td> - - <td>Float[ ]</td> - - <td>Yellow transfer</td> - </tr> -</table> -</blockquote> - -<h3><a name="Uni_honors"></a><code>uniprint</code>'s Roll of Honor</h3> - -<p> -I should mention all of the people who were involved in -<code>stcolor</code>'s evolution, but I've decided to start from scratch -here for <code>uniprint</code>:</p> - -<blockquote> -<dl> -<dt>John P. Beale -<dd>for testing the <code>stc600</code> modes -<dt>Bill Davidson -<dd>who triggered some weaving research and tested <code>stc2s_h</code> -<dt>L. Peter Deutsch -<dd>who triggered ease of configuration -<dt>Mark Goldberg -<dd>who prepared the <code>stc500</code> transfers -<dt>Scott F. Johnston and Scott J. Kramer -<dd>for testing the <code>stc800</code> modes -<dt>Martin Lottermoser -<dd>for his great commented H-P DeskJet driver -<dt>Helmut Riegler -<dd>for the BJC extension -<dt>Hans-Gerd Straeter -<dd>for some measured transfer curves and more -<dt>Uli Wortmann -<dd>for discussions and his <code>cdj850</code> driver -<dt>My family -<dd>for tolerating my printer-driver hacking -</dl> -</blockquote> - -<address> -Gunther Hess<br> -Duesseldorfer Landstr. 16b<br> -D-47249 Duisburg<br> -Germany<br> -+49 203 376273 telephone (MET evening hours)<br> -<<a href="mailto:ghess@elmos.de">ghess@elmos.de</a>> -</address> - -<h3><a name="Uni_weaving_howto"></a><tt>Uniprint</tt> weaving parameters howto</h3> -<p>This section was contributed by Glenn Ramsey.</p> -<p>I wrote this because the documentation was very brief and I really struggled -with it for a while, but it is very simple once you understand what is going -on.</p> -<p>This only describes how to work out the Y parameters, I haven't looked -at the X parameters yet.</p> -<ol> -<li> -<b>Determine the nozzle geometry (upOutputPins)</b> -<p> -You need to know how many nozzles the printer has and the spacing between -them. Usually you can find this out from the printer manual, or the printer -supplier, but you may have to dissect a couple of printer output files -produced with the driver supplied with the printer. There is a utility -called escp2ras<a href="#escp2ras"><sup>*</sup></a> that will help with that. -Sometimes the term pin is used instead of nozzle but they mean the same thing. </p> -<p>The number of nozzles will be the value assigned to the upOutputPins -parameter.</p> -<p>Actually you don't have to print with all the pins available but for -the purpose of demonstration I'll assume that we are using them all.</p> -<p> -<a name="escp2ras"></a>* escp2ras is available from Gunther Hess' page at <a href="http://www-md.e-technik.uni-rostock.de/ma/gunther/gs/index.html">http://www-md.e-technik.uni-rostock.de/ma/gunther/gs/index.html</a></p> -</li> -<li><b>Determine how many passes are required (upWeaveYPasses)</b></li> -<li>The number of passes required is going to depend on the required resolution -and the nozzle spacing. -<blockquote> -<tt>passes = resolution * nozzle spacing -</tt> -</blockquote> -This will be the value assigned to the upWeaveYPasses parameter. -<p>For example if the desired resolution is 360 dpi and the nozzles are -spaced at 1/90in then 360 * 1/90 = 4 passes are required. For 720 dpi 8 -passes would be required. The printer would, of course, have to be capable -of moving the paper in increments of either 360 or 720 dpi too.</p> - - </li> -<li> -<b>Determine the normal Y feed increment (upWeaveYFeeds)</b></p> -<p> -You need to work out how much to feed the paper so that when the paper -has moved by one head length in however many passes you have then each -row space on the paper has been passed over by at least one nozzle. There -will be one feed value for each pass and the feed values must comply with -the following rules:</p> -<blockquote> -<p><tt>sum of feeds = passes * nozzles -<br>feed%passes != 0 (feed is not exactly divisible by passes) -<br>sum of (nozzles - feed) = 0</tt></p> - -</blockquote> -<p>For example if passes=4 and nozzles=15, then sum of feeds=60. The feed -values could be 1,1,1,57 or 15,15,15,15 or 14,15,18,13.</p> -<p>These values will be assigned to the upWeaveYFeeds parameter.</p> -<p>You would need to experiment to see what combination looks best on the -printer.</p> -<p>I found it convenient to draw several lines of nozzles and then move -them around to see how the different combinations would fill the paper. -A computer drawing tool makes this easier than pencil and paper (I used -Dia, a GNOME app). The number of nozzles would probably be be a good place -to start.</p> -<p>Remember that if the number of passes is more than 1 then the feed increment -will be less than the nozzle spacing and <tt>passes × feed increment size</tt> -must equal the physical distance between each nozzle.</p> -<p> -</li> -<li> -<b>Determine the beginning of page pins (upWeaveInitialPins)</b></p> -<p> -These values will be assigned to the upWeaveInitialPins parameter and are -the numbers of nozzles to operate in each of the initial passes at the top -of a page. The nozzles that the values refer to are the topmost nozzles -on the head, nearest the top margin. If the image doesn't start at the -top margin then uniprint doesn't use these feeds.</p> -<p>I don't know a mathematical relation for this except that at least one -of the values must be the number of nozzles, but I'm sure that there must -be one. I used a graphical method, the description that follows refers -to the ascii diagram in below.</p> -<p>Draw a line of nozzles for each pass arranged as they would be using -the normal Y feed increment determined in step 3. In the diagram below -this would be passes 5-8.</p> -<p>Draw a line of nozzles that would print just before the first normal -pass. The feed increment for this pass will be close to and most likely -1 or 2 units less than the feed increment of the last normal pass. In the -example below this line is pass 4 and the feed increment is 13 whereas -the normal feed increment is 15.</p> -<p>Draw each pass before that with a small feed increment so that if all -of the nozzles appearing above the first nozzle of the first normal pass -operate then all of the spaces will be filled. This feed increment is usually -1 except in cases where some jiggery pokery is going on to make the printer -print at an apparent higher resolution than the nozzle diameter.</p> -<p>Now select the nozzles that will operate in each of theses initial passes -so that the paper is filled. In each pass the nozzles must be adjacent -to each other and at least one of the passes will have all the nozzles -operating. I suspect that for each combination of normal Y feed increments -there will only be one set of valid beginning of page increments.</p> -</li> -</ol> -<h4>Example: stc.upp from Aladdin Ghostscript 6.01</h4> -15 nozzles spaced at 1/90 in, 360 dpi requires 4 passes. -<blockquote><pre><tt> --dupWeaveYPasses=4 --dupOutputPins=15 --dupWeaveYFeeds="{15 15 15 15}" --dupWeaveInitialYFeeds="{1 1 1 13}" --dupWeaveInitialPins="{ 4 15 11 7}" -</tt></pre></blockquote> -The following diagram shows which nozzles operate during each pass. -<br>Passes 1-4 are beginning of page passes and passes 5-8 are normal passes. -<blockquote> -<p>x=nozzle operates, o=nozzle not used in this pass<tt></tt></p> -<p><tt> 1 2 3 4 5 6 7 8 - pass no</tt></p> -<br><tt>0 x</tt> -<br><tt>1 x</tt> -<br><tt>2 x</tt> -<br><tt>3 x</tt> -<br><tt>4 x</tt> -<br><tt>5 x</tt> -<br><tt>6 x</tt> -<br><tt>7 x</tt> -<br><tt>8 x</tt> -<br><tt>9 x</tt> -<br><tt>0 x</tt> -<br><tt>1 x</tt> -<br><tt>2 x</tt> -<br><tt>3 x</tt> -<br><tt>4 x</tt> -<br><tt>5 x</tt> -<br><tt>6 o x</tt> -<br><tt>7 x</tt> -<br><tt>8 x</tt> -<br><tt>9 x</tt> -<br><tt>0 o x</tt> -<br><tt>1 x</tt> -<br><tt>2 x</tt> -<br><tt>3 x</tt> -<br><tt>4 o x</tt> -<br><tt>5 x</tt> -<br><tt>6 x</tt> -<br><tt>7 x</tt> -<br><tt>8 o x</tt> -<br><tt>9 x</tt> -<br><tt>0 x</tt> -<br><tt>1 o x</tt> -<br><tt>2 o x</tt> -<br><tt>3 x</tt> -<br><tt>4 x</tt> -<br><tt>5 o x</tt> -<br><tt>6 o x</tt> -<br><tt>7 x</tt> -<br><tt>8 x</tt> -<br><tt>9 o x</tt> -<br><tt>0 o x</tt> -<br><tt>1 x</tt> -<br><tt>2 x</tt> -<br><tt>3 o x</tt> -<br><tt>4 o x</tt> -<br><tt>5 x</tt> -<br><tt>6 o -x</tt> -<br><tt>7 o x</tt> -<br><tt>8 o x</tt> -<br><tt>9 x</tt> -<br><tt>0 o -x</tt> -<br><tt>1 o x</tt> -<br><tt>2 o x</tt> -<br><tt>3 x</tt> -<br><tt>4 o -x</tt> -<br><tt>5 o x</tt> -<br><tt>6 o x</tt> -<br><tt>7 x</tt> -<br><tt>8 o -x</tt> -<br><tt>9 o x</tt> -<br><tt>0 x</tt> -<br><tt>1 -x</tt> -<br><tt>2 -x</tt> -<br><tt>3 x</tt> -<br><tt>4 x</tt> -<br><tt>5 -x</tt> -<br><tt>6 -x</tt> -<br><tt>7 x</tt> -<br><tt>8 x</tt> -<br><tt>9 -x</tt> -<br><tt>0 -x</tt> -<br><tt>1 x</tt> -<br><tt>2 x</tt> -<br><tt>3 -x</tt> -<br><tt>4 -x</tt> -<br><tt>5 x</tt> -<br><tt>6</tt> -<br><tt>7 -x</tt> -<br><tt>8 -x</tt> -<br><tt>9 x</tt> -<br><tt>0</tt> -<br><tt>1 -x</tt> -<br><tt>2 -x</tt> -<br><tt>3 x</tt> -<br><tt>4</tt> -<br><tt>5 -x</tt> -<br><tt>6 -x</tt> -<br><tt>7 x</tt> -<br><tt>8</tt> -<br><tt>9 -x</tt> -<br><tt>0 -x</tt> -<br><tt>1</tt> -<br><tt>2</tt> -<br><tt>3 -x</tt> -<br><tt>4 -x</tt> -<br><tt>5</tt> -<br><tt>6</tt> -<br><tt>7 -x</tt> -<br><tt>8 -x</tt> -<br><tt>9</tt> -<br><tt>0</tt> -<br><tt>1 -x</tt> -<br><tt>2 -x</tt> -<br><tt>3</tt> -<br><tt>4</tt> -<br><tt>5 -x</tt> -<br><tt>6</tt> -<br><tt>7</tt> -<br><tt>8</tt> -<br><tt>9 -x</tt> -<br><tt>0</tt> -<br><tt>1</tt> -<br><tt>2</tt> -<br><tt>3 -x</tt> -<br><tt>4</tt> -<br><tt>5</tt> -<br><tt>6</tt> -<br><tt>7 -x</tt> -</blockquote> -<p>These parameters would also work:</p> -<blockquote><pre><tt> --dupWeaveYPasses=4 --dupOutputPins=15 --dupWeaveYFeeds="{14 15 18 13}" --dupWeaveInitialYFeeds="{1 1 1 13}" --dupWeaveInitialPins="{ 4 11 7 15}" -</tt></pre></blockquote> - -<h3><a name="Uni_esc300"></a>Extension to <tt>uniprint</tt> for the Epson Stylus Color 300</h3> -<p>This section was contributed by Glenn Ramsey. -The Epson Stylus Color 300 uses a different command set to other Epson -Stylus Color printers that use the ESC/P2 language. As far as I can -tell its commands are a subset of ESC/P2. In ESC/P2 the colour to be -printed is selected by a 'set colour' command and then the data sent -is only printed in that colour until the colour is changed with another -'set colour' command. The Stylus Color 300 lacks this functionality. -The data sent to the printer maps directly to the ink nozzles and colour -of an output scan line in the printed output is determined by the position -of the scan line within the data. This means that the driver must know -how the nozzles are arranged and must format the output accordingly. -The extension adds a format that I have called EscNozzleMap and adds some - additional parameters to uniprint.</p><br> -<ul> - <li><code>upOutputFormat</code>selects the output method, and should be set to the value -<code>/EscNozzleMap</code> to select this format. - <blockquote> - <table cellpadding="0" cellspacing="0"> - <tbody> - <tr valign="Top"> - <td><code>/EscNozzleMap</code></td> - - <td>produces output for the Epson Stylus Color 300 - </td> - </tr> - </tbody> - </table> - </blockquote> - </li> -</ul> - -<blockquote> -<table> - <tr> - <th colspan="3">uniprint parameters for the EscNozzleMap format</th> - </tr> - <tr> - <th align="Left">Parameter</th> - - <th align="Left">Type</th> - - <th align="Left">Use</th> - </tr> - <tr> - <td colspan="3"></td> - </tr> - <tr> - <td><code>upNozzleMapRowsPerPass</code></td> - - <td>Int - </td> - - - <td>output rows to generate for each pass of the head - </td> - </tr> - <tr> - <td><code>upNozzleMapPatternRepeat</code></td> - - <td>Int - </td> - - <td>no. of rows that correspond to the repeat pattern of the - nozzles - </td> - </tr> - <tr> - <td><code>upNozzleMapRowMask</code></td> - <td>Int[] - </td> - <td>mask indicating the colour of the nozzles - </td> - </tr> - <tr> - <td><code>upNozzleMapMaskScanOffset</code></td> - - <td>Int[] - </td> - <td>mask indicating the physical position of the nozzles - </td> - </tr> - </table> -</blockquote> - -<h4>A more detailed description of the new parameters</h4> -<ul> - <li><code>upNozzleMapRowsPerPass</code><br> - The number of rows of data that are required to address all nozzles for a - single pass of the head. There will always be this number of rows of output - data generated. I'd expect it to be the same as the total number of nozzles but - it wouldn't break the formatter if it wasn't. So if you wanted to print with - only the 10th nozzle then row 10 would contain data corresponding to the bit - pattern and all of the others would be padded with zeros. - </li> - <li><code>upNozzleMapPatternRepeat</code><br> - The number of nozzles in each repeated group on the printing head. - This parameter must correspond with the length of the upNozzleMapRowMask array. - </li> - <li><code>upNozzleMapRowMask</code><br> - An array of integers that defines the colour of the nozzles on the - head and whether the nozzles will be used to print. The array index - defines the row index for the nozzle in the output data - and the value defines the colour of the nozzle. The mapping - of colours to values is defined in the table below. - <blockquote> - <table> - <tr> - <th align="center">colour - </th> - - <th align="center">mask value - </th> - </tr> - <tr valign="Top" align="center"> - <td><code>K</code></td> - - <td>1 - </td> - </tr> - <tr valign="Top" align="center"> - <td><code>C</code></td> - - <td>2 - </tr> - <tr valign="Top" align="center"> - <td><code>M</code></td> - - <td>3 - </td> - </tr> - <tr valign="Top" align="center"> - <td><code>Y</code></td> - - <td>4 - </td> - </tr> - <tr valign="Top" align="center"> - <td><code>no data</code></td> - - <td>0 - </td> - </tr> - </tbody> - </table> - </blockquote> - A value of 0 means that the nozzle is not used and the row in the output data will be - padded with zeros.<br> - </li> - - <li><code>upNozzleMapMaskScanOffset</code><br> - An array of integers that defines the physical position of the nozzles relative - to the first nozzle in the repeated group. The relative distance is measured in - printed line widths and will be different for different printing resolutions. - This parameter is used because the physical spacing of the nozzles may not - correspond to their mapping in the output data. For example the ESC300 has nozzles - physically arranged something like this: -<p></p> - <table> - <tr> - <td bgcolor="#00ffff"> - </td> - <td bgcolor="#ffff00"> - </td> - <td bgcolor="#000000"> - </td> - <td bgcolor="#ff00ff"> - </td> - <td bgcolor="#000000"> - </td> - <td> - </td> - <td bgcolor="#000000"> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td bgcolor="#00ffff"> - </td> - <td bgcolor="#ffff00"> - </td> - <td bgcolor="#000000"> - </td> - <td bgcolor="#ff00ff"> - </td> - <td bgcolor="#000000"> - </td> - <td> - </td> - <td bgcolor="#000000"> - </td> - <td bgcolor="#ffffff"> - </td> - </tr> - <tr> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td bgcolor="#00ffff"> - </td> - <td bgcolor="#ffff00"> - </td> - <td bgcolor="#000000"> - </td> - <td bgcolor="#ff00ff"> - </td> - <td bgcolor="#000000"> - </td> - <td> - </td> - <td bgcolor="#000000"> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td> - </td> - <td bgcolor="#00ffff"> - </td> - <td bgcolor="#ffff00"> - </td> - <td>etc ... - </td> - </tr> - </table> - -<p>There is a one nozzle width space between the last two nozzles in each group. - In the output data the data for the last nozzle in the group would be in row 5 - (numbering starts at 0) but the nozzle is physically positioned at 6 spaces from - the first nozzle. </p> - - </li> -</ul> -<h4>Example 1 - Epson Stylus Color 300 - 360 dpi colour</h4> -<blockquote><pre> --dupWeaveYPasses=6 --dupOutputPins=11 --dupWeaveYFeeds="{ 11 11 11 11 11 11 }" --dupWeaveInitialYFeeds="{ 1 1 1 1 1 7 }" --dupWeaveInitialPins="{ 2 11 9 7 5 3 }" --dupNozzleMapRowsPerPass=64 --dupNozzleMapPatternRepeat=6 --dupNozzleMapRowMask="{ 2 4 1 3 0 0 }" --dupNozzleMapMaskScanOffset="{ 0 1 2 3 0 0 }" -</pre></blockquote> -The weaving parameters are the same as for any other uniprint driver -but they must be consistent with the nozzle map parameters. In this printer -the coloured nozzles are spaced at 1/60" so 6 passes are required for 360 -dpi resolution. -<p> -In the example there are 64 rows of data required for each head pass. Each -row must be completely filled with data for each pass so if certain nozzles -do not print in the pass then the rows for those nozzles will be padded -with zeroes.</p> -<P> -The row mask translates to "C Y K M 0 0" so in the output data rows 0,7,13,... -will contain data for cyan, rows 1,8,14,... will contain data for yellow, etc. Rows 4,10,16,... -and 5, 11,15,... will always be padded with zeroes. The <i>upNozzleMapPatternRepeat</i> -parameter defines the length of the mask.</p> -<p> -The row mask is repeated for each group of <i>upNozzleMapPatternRepeat</i> rows -in the output data. In this case there are 64 rows so there will be 10 groups -of "C Y K M 0 0" followed by "C Y K M" which is equivalent to 11 output -pins.</p> -<P> -The <i>upNozzleMaskScanOffset</i> array indicates how the data from the scan -buffer is mapped to the output data. The data is presented to the formatter -as a buffer of four colour scanlines. The index of the scanline being printed, -lets call it y, always corresponds, in this example, to the physical position of -the cyan nozzle but since the nozzles are not on the same horizontal -line then the other colours for the current pass must come from other -scanlines in the scan buffer. The example is { 0 1 2 3 0 0 }, this means that -when printing a 4 colour image the magenta data would come from scanline y+3, -the black from scanline y+2, etc. It would have been possible in this case -to use the array index instead of the <i>upNozzleMaskScanOffset</i> parameter -however the parameter is necessary to be able to use the full capability of the -printer in black only mode.</p> - -<h4>Example 2 - Epson Stylus Color 300 - 180 dpi black only</h4> -<blockquote> -<pre> --dupMargins="{ 9.0 39.96 9.0 9.0}" --dupWeaveYPasses=1 --dupOutputPins=31 --dupNozzleMapRowsPerPass=64 --dupNozzleMapPatternRepeat=6 --dupNozzleMapRowMask="{ 0 0 1 0 1 1}" --dupNozzleMapMaskScanOffset="{ 0 0 0 0 1 2 }" -</pre> -</blockquote> -In this example there is no weaving. -<p> -The ESC300 has black nozzles evenly physically arranged as K K K but the data must -be sent to the printer as 00K0KK. This is handled by the <i>upNozzleMapRowMask</i> -and <i>upNozzleMaskScanOffset</i> arrays. The <i>upNozzleMapRowMask</i> array is -{ 0 0 1 0 1 1} which translates to { 0 0 K 0 K K } so rows 0, 1 and 3 will always -contain zeros and the other rows will contain data.</p> -<p> -The <i>upNozzleMaskScanOffset</i> array -in this case is { 0 0 0 0 1 2 } so if the data for the 1st nozzle comes from row -y in the scan buffer then the data for the 2nd and 3rd nozzles will come from rows -y+1 and y+2.</p> - -<h4>Example 3 - Epson Stylus Color 300 - 360 dpi black only</h4> -<blockquote> -<pre> --dupWeaveYPasses=2 --dupOutputPins=31 --dupWeaveYFeeds="{31 31}" --dupWeaveInitialYFeeds="{1 31}" --dupWeaveInitialPins="{16 31}" --dupNozzleMapRowsPerPass=64 --dupNozzleMapPatternRepeat=6 --dupNozzleMapRowMask="{ 0 0 1 0 1 1}" --dupNozzleMapMaskScanOffset="{ 0 0 0 0 2 4 }" -</pre> -</blockquote> -In this example 2 weave passes are required to achieve the desired resolution. -<p> -The <i>upNozzleMaskScanOffset</i> array in this case is { 0 0 0 0 2 4 } because -there are two weave passes so if the data for the first nozzle comes from row y -in the scan buffer then the data for the 2nd and 3rd nozzles must come from rows -y+(1*2) and y+(2*2).</p> -<p> -<address> -Glenn Ramsey<br> -glennr at users.sourceforge.net<br> -February 2001 -</address></p> -<br> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Develop.htm b/doc/Develop.htm deleted file mode 100644 index b74edfbd..00000000 --- a/doc/Develop.htm +++ /dev/null @@ -1,4823 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Information for Ghostscript Developers</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Information for Ghostscript Developers</h1> -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Introduction">Introduction</a></li> - <li><a href="#Architecture">Architecture</a></li> - <li> - <ul> - <li><a href="#Design_goals">Design goals</a></li> - <li><a href="#Design_principles">Design principles</a></li> - <li><a href="#Large_scale_structure">Large-scale structure</a></li> - <li><a href="#Object_oriented_constructs">Object-oriented constructs</a></li> - </ul> - </li> - <li><a href="#File_roadmap">File roadmap</a></li> - <li> - <ul> - <li><a href="#Substrate">Substrate</a></li> - <li><a href="#Graphics_library">Graphics library</a></li> - <li> - <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> - </li> - </ul> - </li> - <li><a href="#Device_drivers">Device drivers</a></li> - <li> - <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></li> - </ul> - </li> - <li><a href="#PostScript_interpreter">PostScript interpreter</a></li> - <li> - <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></li> - </ul> - </li> - <li><a href="#PDF_interpreter">PDF interpreter</a></li> - <li><a href="#PPD">PostScript Printer Description</a></li> - <li><a href="#Build_process">Build process</a></li> - <li> - <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></li> - </ul> - </li> - <li><a href="#Utilities">Utilities</a></li> - <li> - <ul> - <li><a href="#Utilities_in_PostScript">Utilities in PostScript</a></li> - <li><a href="#Utility_scripts">Utility scripts</a></li> - </ul> - </li> - </ul> - </li> - <li><a href="#Memory_management">Memory management</a></li> - <li> - <ul> - <li><a href="#Memory_manager_architecture">Memory manager architecture</a></li> - <li> - <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> - </li> - </ul> - </li> - <li><a href="#Freeing_storage">Freeing storage</a></li> - <li> - <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> - </li> - </ul> - </li> - <li><a href="#Special_implementations">Special implementations</a></li> - <li> - <ul> - <li><a href="#malloc">malloc</a>, - <a href="#Locking">Locking</a>, - <a href="#Retrying">Retrying</a>, - <a href="#Chunk">Chunk</a> - </li> - </ul> - </li> - <li><a href="#Standard_implementation">Standard implementation</a></li> - <li><a href="#PostScript_interpreter_extensions">PostScript interpreter extensions</a></li> - <li> - <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></li> - </ul> - </li> - </ul> - </li> - <li><a href="#Portability">Portability</a></li> - <li> - <ul> - <li><a href="#Structural">Structural</a></li> - <li> - <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> - </li> - </ul> - </li> - <li><a href="#Coding">Coding</a></li> - <li> - <ul> - <li><a href="#Explicit_dependencies">Explicit dependencies</a>, - <a href="#Implicit_dependencies">Implicit dependencies</a></li> - </ul> - </li> - <li><a href="#Platform_specific_code">Platform-specific code</a></li> - </ul> - </li> - - <li><a href="#Troubleshooting">Troubleshooting and debugging</a></li> - <li><a href="#Profiling">Profiling</a></li> - <li> - <ul> - <li><a href="#ProfilingMSVC6">Profiling with Microsoft Developer Studio 6</a></li> - </ul> - </li> -</ul> - - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</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. -<hr> -<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 <code>gs_error_NeedInput</code> 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 -<code>stdin</code> and output to <code>stdout</code> and -<code>stderr</code>. - -<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="../base/gslibctx.h">base/gslibctx.h</a>, -<a href="../base/gslibctx.c">base/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="../base/gsdsrc.c">base/gsdsrc.c</a>, -<a href="../base/gsdsrc.h">base/gsdsrc.h</a>, -<a href="../base/scommon.h">base/scommon.h</a>, -<a href="../base/strmio.c">base/strmio.c</a>, -<a href="../base/strmio.h">base/strmio.h</a>, -<a href="../base/sfxboth.c">base/sfxboth.c</a>, -<a href="../base/sfxfd.c">base/sfxfd.c</a>, -<a href="../base/sfxstdio.c">base/sfxstdio.c</a>, -<a href="../base/sfxcommon.c">base/sfxcommon.c</a>, -<a href="../base/stream.h">base/stream.h</a>, -<a href="../base/stream.c">base/stream.c</a>, -<a href="../base/strimpl.h">base/strimpl.h</a>. - -<dt> -Standard filters: -<dd> - -<dl> - -<dt> -CCITTFax: -<dd> -<a href="../base/scf.h">base/scf.h</a>, -<a href="../base/scfd.c">base/scfd.c</a>, -<a href="../base/scfdgen.c">base/scfdgen.c</a>, -<a href="../base/scfdtab.c">base/scfdtab.c</a>, -<a href="../base/scfe.c">base/scfe.c</a>, -<a href="../base/scfetab.c">base/scfetab.c</a>, -<a href="../base/scfparam.c">base/scfparam.c</a>, -<a href="../base/scfx.h">base/scfx.h</a>. - -<dt> -DCT (JPEG): -<dd> -<a href="../base/gsjconf.h">base/gsjconf.h</a>, -<a href="../base/gsjmorec.h">base/gsjmorec.h</a>, -<a href="../base/sdcparam.c">base/sdcparam.c</a>, -<a href="../base/sdcparam.h">base/sdcparam.h</a>, -<a href="../base/sdct.h">base/sdct.h</a>, -<a href="../base/sdctc.c">base/sdctc.c</a>, -<a href="../base/sdctd.c">base/sdctd.c</a>, -<a href="../base/sdcte.c">base/sdcte.c</a>, -<a href="../base/sddparam.c">base/sddparam.c</a>, -<a href="../base/sdeparam.c">base/sdeparam.c</a>, -<a href="../base/sjpeg.h">base/sjpeg.h</a>, -<a href="../base/sjpegc.c">base/sjpegc.c</a>, -<a href="../base/sjpegd.c">base/sjpegd.c</a>, -<a href="../base/sjpege.c">base/sjpege.c</a>. - -<dt> -JBIG2: -<a href="../base/sjbig2.h">base/sjbig2.h</a>, -<a href="../base/sjbig2.c">base/sjbig2.c</a> -<dt> -JPX (JPEG 2000): -<a href="../base/sjpx_openjpeg.h">base/sjpx_openjpeg.h</a>, -<a href="../base/sjpx_openjpeg.c">base/sjpx_openjpeg.c</a> -<dt> -Other compression/decompression: -<dd> -<a href="../base/slzwc.c">base/slzwc.c</a>, -<a href="../base/slzwd.c">base/slzwd.c</a>, -<a href="../base/slzwe.c">base/slzwe.c</a>, -<a href="../base/slzwx.h">base/slzwx.h</a>, -<a href="../base/srld.c">base/srld.c</a>, -<a href="../base/srle.c">base/srle.c</a>, -<a href="../base/srlx.h">base/srlx.h</a>. - -<dt> -Other: -<dd> -<a href="../base/sa85d.c">base/sa85d.c</a>, -<a href="../base/sa85d.h">base/sa85d.h</a>, -<a href="../base/sa85x.h">base/sa85x.h</a>, -<a href="../psi/sfilter1.c">psi/sfilter1.c</a>, -<a href="../base/sfilter2.c">base/sfilter2.c</a>, -<a href="../base/sstring.c">base/sstring.c</a>, -<a href="../base/sstring.h">base/sstring.h</a>. - -</dl> - -<dt> -Non-standard filters used to implement standard filters: -<dd> -<a href="../base/seexec.c">base/seexec.c</a>, -<a href="../base/sfilter.h">base/sfilter.h</a>, -<a href="../base/shc.c">base/shc.c</a>, -<a href="../base/shc.h">base/shc.h</a>, -<a href="../base/spdiff.c">base/spdiff.c</a>, -<a href="../base/spdiffx.h">base/spdiffx.h</a>, -<a href="../base/spngp.c">base/spngp.c</a>, -<a href="../base/spngpx.h">base/spngpx.h</a>, -<a href="../base/szlibc.c">base/szlibc.c</a>, -<a href="../base/szlibd.c">base/szlibd.c</a>, -<a href="../base/szlibe.c">base/szlibe.c</a>, -<a href="../base/szlibx.h">base/szlibx.h</a>, -<a href="../base/szlibxx.h">base/szlibxx.h</a>. - -<dt> -Non-standard filters: -<dd> -<a href="../base/sbcp.c">base/sbcp.c</a>, -<a href="../base/sbcp.h">base/sbcp.h</a>, -<a href="../base/sbtx.h">base/sbtx.h</a>, -<a href="../base/smd5.c">base/smd5.c</a>, -<a href="../base/smd5.h">base/smd5.h</a>, -<a href="../base/saes.c">base/saes.c</a>, -<a href="../base/saes.h">base/saes.h</a>, -<a href="../base/sarc4.c">base/sarc4.c</a>, -<a href="../base/sarc4.h">base/sarc4.h</a>, - -<dt> -Internal filters: -<dd> -<a href="../base/siinterp.c">base/siinterp.c</a>, -<a href="../base/siinterp.h">base/siinterp.h</a>, -<a href="../base/siscale.c">base/siscale.c</a>, -<a href="../base/siscale.h">base/siscale.h</a>, -<a href="../base/sidscale.c">base/sidscale.c</a>, -<a href="../base/sidscale.h">base/sidscale.h</a>, -<a href="../base/sisparam.h">base/sisparam.h</a>. - -<dt> -Higher-level stream support: -<dd> -<a href="../base/spprint.c">base/spprint.c</a>, -<a href="../base/spprint.h">base/spprint.h</a>, -<a href="../base/spsdf.c">base/spsdf.c</a>, -<a href="../base/spsdf.h">base/spsdf.h</a>, -<a href="../base/srdline.h">base/srdline.h</a>. - -</dl> - -<h4>Platform-specific code</h4> - -See <a href="#Cross_platform_APIs">below</a>. - -<h4>Miscellaneous</h4> - -<dl> - -<dt> -Library top level: -<dd> -<a href="../base/gsinit.c">base/gsinit.c</a>, -<a href="../base/gslib.h">base/gslib.h</a>. - -<dt> -Configuration-related: -<dd> -<a href="../base/gconf.c">base/gconf.c</a>, -<a href="../base/gconf.h">base/gconf.h</a>, -<a href="../base/gscdef.c">base/gscdef.c</a>, -<a href="../base/gscdefs.h">base/gscdefs.h</a>, -<a href="../base/gsromfs0.c">base/gsromfs0.c</a>. - -<dt> -Arithmetic: -<dd> -<a href="../base/gxarith.h">base/gxarith.h</a>, -<a href="../base/gxdda.h">base/gxdda.h</a>, -<a href="../base/gxfarith.h">base/gxfarith.h</a>, -<a href="../base/gxfixed.h">base/gxfixed.h</a>, -<a href="../base/gxfrac.h">base/gxfrac.h</a>. - -<dt> -Operating system interface: -<dd> -<a href="../base/gserrors.h">base/gserrors.h</a>, -<a href="../base/gsexit.h">base/gsexit.h</a>, -<a href="../base/gxstdio.h">base/gxstdio.h</a>, -<a href="../base/gxsync.c">base/gxsync.c</a>, -<a href="../base/gxsync.h">base/gxsync.h</a>. - -<dt> -Other: -<dd> -<a href="../base/gsargs.c">base/gsargs.c</a>, -<a href="../base/gsargs.h">base/gsargs.h</a>, -<a href="../base/gserrors.h">base/gserrors.h</a>, -<a href="../base/gsnotify.c">base/gsnotify.c</a>, -<a href="../base/gsnotify.h">base/gsnotify.h</a>, -<a href="../base/gsrect.h">base/gsrect.h</a>, -<a href="../base/gstypes.h">base/gstypes.h</a>, -<a href="../base/gsuid.h">base/gsuid.h</a>, -<a href="../base/gsutil.h">base/gsutil.h</a>, -<a href="../base/gsutil.c">base/gsutil.c</a>, -<a href="../base/gx.h">base/gx.h</a>, -<a href="../base/gsmd5.c">base/gsmd5.c</a>, -<a href="../base/gsmd5.h">base/gsmd5.h</a>, -<a href="../base/aes.c">base/aes.c</a>, -<a href="../base/aes.h">base/aes.h</a>. - -</dl> - -<h3><a name="Graphics_library"></a>Graphics library</h3> - -<h4><a name="Library_support"></a>Support</h4> - -<dl> - -<dt> -Bitmap processing: -<dd> -<a href="../base/gsbitcom.c">base/gsbitcom.c</a>, -<a href="../base/gsbitmap.h">base/gsbitmap.h</a>, -<a href="../base/gsbitops.c">base/gsbitops.c</a>, -<a href="../base/gsbitops.h">base/gsbitops.h</a>, -<a href="../base/gsbittab.c">base/gsbittab.c</a>, -<a href="../base/gsbittab.h">base/gsbittab.h</a>, -<a href="../base/gsflip.c">base/gsflip.c</a>, -<a href="../base/gsflip.h">base/gsflip.h</a>, -<a href="../base/gxbitmap.h">base/gxbitmap.h</a>, -<a href="../base/gxbitops.h">base/gxbitops.h</a>, -<a href="../base/gxsample.c">base/gxsample.c</a>, -<a href="../base/gxsample.h">base/gxsample.h</a>. -<a href="../base/gxsamplp.h">base/gxsamplp.h</a>. - -<dt> -Functions: -<dd> -<a href="../base/gsfunc.c">base/gsfunc.c</a>, -<a href="../base/gsfunc.h">base/gsfunc.h</a>, -<a href="../base/gsfunc0.c">base/gsfunc0.c</a>, -<a href="../base/gsfunc0.h">base/gsfunc0.h</a>, -<a href="../base/gsfunc3.c">base/gsfunc3.c</a>, -<a href="../base/gsfunc3.h">base/gsfunc3.h</a>, -<a href="../base/gsfunc4.c">base/gsfunc4.c</a>, -<a href="../base/gsfunc4.h">base/gsfunc4.h</a>, -<a href="../base/gxfunc.h">base/gxfunc.h</a>. - -<dt> -Parameter lists: -<dd> -<a href="../base/gscparam.c">base/gscparam.c</a>, -<a href="../base/gsparam.c">base/gsparam.c</a>, -<a href="../base/gsparam.h">base/gsparam.h</a>, -<a href="../base/gsparam2.c">base/gsparam2.c</a> (not used), -<a href="../base/gsparams.c">base/gsparams.c</a>, -<a href="../base/gsparams.h">base/gsparams.h</a>, -<a href="../base/gsparamx.c">base/gsparamx.c</a>, -<a href="../base/gsparamx.h">base/gsparamx.h</a>. - -<dt> -I/O-related: -<dd> -<a href="../base/gdevpipe.c">base/gdevpipe.c</a>, -<a href="../base/gsfname.c">base/gsfname.c</a>, -<a href="../base/gsfname.h">base/gsfname.h</a>, -<a href="../base/gsio.h">base/gsio.h</a>, -<a href="../base/gsiodev.c">base/gsiodev.c</a>, -<a href="../base/gsiodevs.c">base/gsiodevs.c</a>, -<a href="../base/gsiodisk.c">base/gsiodisk.c</a>, -<a href="../base/gsiorom.c">base/gsiorom.c</a>. -<a href="../base/gsiorom.h">base/gsiorom.h</a>. -<a href="../base/gxiodev.h">base/gxiodev.h</a>. - -</dl> - -<h4><a name="Paths"></a>Paths</h4> - -<dl> - -<dt> -Coordinate transformation: -<dd> -<a href="../base/gscoord.c">base/gscoord.c</a>, -<a href="../base/gscoord.h">base/gscoord.h</a>, -<a href="../base/gsmatrix.c">base/gsmatrix.c</a>, -<a href="../base/gsmatrix.h">base/gsmatrix.h</a>, -<a href="../base/gxcoord.h">base/gxcoord.h</a>, -<a href="../base/gxmatrix.h">base/gxmatrix.h</a>. - -<dt> -Path building: -<dd> -<a href="../base/gsdps1.c">base/gsdps1.c</a>, -<a href="../base/gspath.c">base/gspath.c</a>, -<a href="../base/gspath.h">base/gspath.h</a>, -<a href="../base/gspath1.c">base/gspath1.c</a>, -<a href="../base/gspath2.h">base/gspath2.h</a>, -<a href="../base/gxpath.c">base/gxpath.c</a>, -<a href="../base/gxpath.h">base/gxpath.h</a>, -<a href="../base/gxpath2.c">base/gxpath2.c</a>, -<a href="../base/gxpcopy.c">base/gxpcopy.c</a>, -<a href="../base/gxpdash.c">base/gxpdash.c</a>, -<a href="../base/gxpflat.c">base/gxpflat.c</a>, -<a href="../base/gzpath.h">base/gzpath.h</a>. - -<dt> -Path rendering: -<dd> -<a href="../base/gdevddrw.c">base/gdevddrw.c</a>, -<a href="../base/gdevddrw.h">base/gdevddrw.h</a>, -<a href="../base/gxdtfill.h">base/gxdtfill.h</a>, -<a href="../base/gsdps1.c">base/gsdps1.c</a>, -<a href="../base/gspaint.c">base/gspaint.c</a>, -<a href="../base/gspaint.h">base/gspaint.h</a>, -<a href="../base/gspenum.h">base/gspenum.h</a>, -<a href="../base/gxfill.c">base/gxfill.c</a>, -<a href="../base/gxfill.h">base/gxfill.h</a>, -<a href="../base/gxfillsl.h">base/gxfillsl.h</a>, -<a href="../base/gxfilltr.h">base/gxfilltr.h</a>, -<a href="../base/gxfillts.h">base/gxfillts.h</a>, -<a href="../base/gximask.c">base/gximask.c</a>, -<a href="../base/gximask.h">base/gximask.h</a>, -<a href="../base/gxfdrop.c">base/gxfdrop.c</a>, -<a href="../base/gxfdrop.h">base/gxfdrop.h</a>, -<a href="../base/gxpaint.c">base/gxpaint.c</a>, -<a href="../base/gxpaint.h">base/gxpaint.h</a>, -<a href="../base/gxstroke.c">base/gxstroke.c</a>, -<a href="../base/gzspotan.c">base/gzspotan.c</a>, -<a href="../base/gzspotan.h">base/gzspotan.h</a>. - -<dt> -Clipping: -<dd> -See under <a href="#Clipping">Clipping</a> below. - -</dl> - -<h4><a name="Text"></a>Text</h4> - -<dl> - -<dt> -Fonts, generic: -<dd> -<a href="../base/gsfont.c">base/gsfont.c</a>, -<a href="../base/gsfont.h">base/gsfont.h</a>, -<a href="../devices/gxfcopy.c">devices/gxfcopy.c</a>, -<a href="../devices/gxfcopy.h">devices/gxfcopy.h</a>, -<a href="../base/gxfont.h">base/gxfont.h</a>. - -<dt> -Fonts, specific FontTypes: -<dd> -<a href="../base/gsfcid.c">base/gsfcid.c</a>, -<a href="../base/gsfcid2.c">base/gsfcid.c</a>, -<a href="../base/gsfcmap.c">base/gsfcmap.c</a>, -<a href="../base/gsfcmap1.c">base/gsfcmap1.c</a>, -<a href="../base/gsfcmap.h">base/gsfcmap.h</a>, -<a href="../base/gsfont0.c">base/gsfont0.c</a>, -<a href="../base/gsfont0c.c">base/gsfont0c.c</a>, -<a href="../base/gxcid.h">base/gxcid.h</a>, -<a href="../base/gxfcid.h">base/gxfcid.h</a>, -<a href="../base/gxfcmap.h">base/gxfcmap.h</a>, -<a href="../base/gxfcmap1.h">base/gxfcmap1.h</a>, -<a href="../base/gxfont0.h">base/gxfont0.h</a>, -<a href="../base/gxfont0c.h">base/gxfont0c.h</a>, -<a href="../base/gxfont1.h">base/gxfont1.h</a>, -<a href="../base/gxfont42.h">base/gxfont42.h</a>, -<a href="../base/gxftype.h">base/gxftype.h</a>, -<a href="../base/gxttf.h">base/gxttf.h</a>. - -<dt> -Character rendering + font cache, generic: -<dd> -<a href="../base/gsccode.h">base/gsccode.h</a>, -<a href="../base/gschar.c">base/gschar.c</a>, -<a href="../base/gschar.h">base/gschar.h</a>, -<a href="../base/gscpm.h">base/gscpm.h</a>, -<a href="../base/gsgdata.c">base/gsgdata.c</a>, -<a href="../base/gsgdata.h">base/gsgdata.h</a>, -<a href="../base/gsgcache.c">base/gsgcache.c</a>, -<a href="../base/gsgcache.h">base/gsgcache.h</a>, -<a href="../base/gstext.c">base/gstext.c</a>, -<a href="../base/gstext.h">base/gstext.h</a>, -<a href="../base/gxbcache.c">base/gxbcache.c</a>, -<a href="../base/gxbcache.h">base/gxbcache.h</a>, -<a href="../base/gxccache.c">base/gxccache.c</a>, -<a href="../base/gxccman.c">base/gxccman.c</a>, -<a href="../base/gxchar.c">base/gxchar.c</a>, -<a href="../base/gxchar.h">base/gxchar.h</a>, -<a href="../base/gxfcache.h">base/gxfcache.h</a>, -<a href="../base/gxtext.h">base/gxtext.h</a>. - -<dt> -Character rendering, specific FontTypes: -<dd> -<a href="../base/gschar0.c">base/gschar0.c</a>, -<a href="../base/gscrypt1.c">base/gscrypt1.c</a>, -<a href="../base/gscrypt1.h">base/gscrypt1.h</a>, -<a href="../base/gstype1.c">base/gstype1.c</a>, -<a href="../base/gstype1.h">base/gstype1.h</a>, -<a href="../base/gstype2.c">base/gstype2.c</a>, -<a href="../base/gstype42.c">base/gstype42.c</a>, -<a href="../base/gxchrout.c">base/gxchrout.c</a>, -<a href="../base/gxchrout.h">base/gxchrout.h</a>, -<a href="../base/gxhintn.h">base/gxhintn.h</a>, -<a href="../base/gxhintn.c">base/gxhintn.c</a>, -<a href="../base/gxhintn1.c">base/gxhintn1.c</a>, -<a href="../base/gxtype1.c">base/gxtype1.c</a>, -<a href="../base/gxtype1.h">base/gxtype1.h</a>. - -</dl> - -<h4><a name="Images"></a>Images</h4> - -<dl> - -<dt> -Buffered API (mostly for PostScript interpreter): -<dd> -<a href="../base/gsimage.c">base/gsimage.c</a>, -<a href="../base/gsimage.h">base/gsimage.h</a>. - -<dt> -Generic support: -<dd> -<a href="../base/gsiparam.h">base/gsiparam.h</a>, -<a href="../base/gxiclass.h">base/gxiclass.h</a>, -<a href="../base/gximage.c">base/gximage.c</a>, -<a href="../base/gximage.h">base/gximage.h</a>, -<a href="../base/gxiparam.h">base/gxiparam.h</a>. - -<dt> -Type 1 and 4 images: -<dd> - -<dl> - -<dt> -Setup: -<dd> -<a href="../base/gsiparm4.h">base/gsiparm4.h</a>, -<a href="../base/gximage1.c">base/gximage1.c</a>, -<a href="../base/gximage4.c">base/gximage4.c</a>. - -<dt> -Rendering: -<dd> -<a href="../base/gxi12bit.c">base/gxi12bit.c</a>, -<a href="../base/gxi16bit.c">base/gxi16bit.c</a>, -<a href="../base/gxicolor.c">base/gxicolor.c</a>, -<a href="../base/gxidata.c">base/gxidata.c</a>, -<a href="../base/gxifast.c">base/gxifast.c</a>, -<a href="../base/gximono.c">base/gximono.c</a>, -<a href="../base/gxino12b.c">base/gxino12b.c</a>, -<a href="../base/gxino16b.c">base/gxino16b.c</a>, -<a href="../base/gxipixel.c">base/gxipixel.c</a>, -<a href="../base/gxiscale.c">base/gxiscale.c</a>. - -</dl> - -<dt> -Type 2 images (Display PostScript): -<dd> -<a href="../base/gsiparm2.h">base/gsiparm2.h</a>, -<a href="../base/gximage2.c">base/gximage2.c</a>. - -<dt> -Type 3 images: -<dd> -<a href="../base/gsipar3x.h">base/gsipar3x.h</a>, -<a href="../base/gsiparm3.h">base/gsiparm3.h</a>, -<a href="../base/gximag3x.c">base/gximag3x.c</a>, -<a href="../base/gximag3x.h">base/gximag3x.h</a>, -<a href="../base/gximage3.c">base/gximage3.c</a>, -<a href="../base/gximage3.h">base/gximage3.h</a>. - -<dt> -Other: -<dd> -<a href="../base/gsimpath.c">base/gsimpath.c</a>, -<a href="../base/simscale.c">base/simscale.c</a>, -<a href="../base/simscale.h">base/simscale.h</a>. -. - -</dl> - -<h4><a name="Paint"></a>Paint</h4> - -<p> -Ghostscript uses 4 internal representations of color. We list them here in -the order in which they occur in the rendering pipeline. - -<ol> - -<li>Clients of the graphics library normally specify colors using the -<em>client color</em> structure (<code>gs_client_color</code>, defined in -<a href="../psi/gs.color.h">psi/gs.color.h</a>), consisting of one or more -numeric values and/or a pointer to a Pattern instance. This corresponds -directly to the values that would be passed to the PostScript -<code>setcolor</code> operator: one or more (floating-point) numeric -components and/or a Pattern. Client colors are interpreted relative to a -color space (<code>gs_color_space</code>, defined in <a -href="../base/gscspace.h">base/gscspace.h</a> and <a -href="../base/gxcspace.h">base/gxcspace.h</a>, with specific color spaces -defined in other files). Client colors do not explicitly reference the -color space in which they are are interpreted: <code>setcolor</code> uses -the color space in the graphics state, while images and shadings explicitly -specify the color space to be used. - -<li>For ordinary non-Pattern colors, the first step in color rendering -reduces a client color to a <em>concrete</em> color -- a set of values in a -color space that corresponds to the device's color model (except for -possible conversions between DeviceGray, DeviceRGB, and DeviceCMYK), -together with an identification of the associated color space. (The -confusion here between color spaces and color models will have to be cleaned -up when we implement native Separation/DeviceN colors.) Concrete colors are -like the numeric values in a client color, except that they are represented -by arrays of <code>frac</code> values (defined in <a -href="../base/gxfrac.h">base/gxfrac.h</a>) rather than floats. The procedure -for this step is the virtual <code>concretize_color</code> and -<code>concrete_space</code> procedures in the (original) color space. -This step reduces Indexed colors, CIEBased colors, and Separation and -DeviceN colors that use the alternate space. - -<li>The final step requires mapping a concrete color to the device's color -model, done by procedures in <a href="../base/gxcmap.c">base/gxcmap.c</a>. -These procedures combine the following three conceptual sub-steps: - -<ul> - -<li>A possible mapping between Device color spaces, possibly involving black -generation and undercolor removal. The non-trivial cases are implemented in -<a href="../base/gxdcconv.c">base/gxdcconv.c</a>. - -<li>Application of the transfer function(s) (done in-line). - -<li>Halftoning if necessary: see below. - -</ul> - -The result is called (inappropriately) a <em>device color</em> -(<code>gx_device_color</code>, defined in <a -href="../psi/gs.color.h">psi/gs.color.h</a> and <a -href="../base/gxdcolor.h">base/gxdcolor.h</a>). For ordinary non-Pattern -colors, a device color is either a pure color, or a halftone. The device -and color model associated with a device color are implicit. The procedure -for this step is the virtual <code>remap_concrete_color</code> procedure -in the color space. - -<li>The pure colors that underlie a device color are opaque <em>pixel -values</em> defined by the device (misnamed <code>gx_color_index</code>, -defined in <a href="../base/gscindex.h">base/gscindex.h</a>). The device with -which they are associated is implicit. Although the format and -interpretation of a pixel value are known only to the device, the device's -color model and color representation capabilities are public, defined by a -<code>gx_color_info</code> structure stored in the device (defined in <a -href="../base/gxdevcli.h">base/gxdevcli.h</a>). Virtual procedures of the -device driver map between pixel values and RGB or CMYK. (This area is -untidy and will need to be cleaned up when we implement native -Separation/DeviceN colors.) - -</ol> - -<p> -Steps 2 and 3 are normally combined into a single step for efficiency, as -the <code>remap_color</code> virtual procedure in a color space. - -<p> -Using a device color to actually paint pixels requires a further step called -<em>color loading</em>, implemented by the <code>load</code> virtual -procedure in the device color. This does nothing for pure colors, but loads -the caches for halftones and Patterns. - -<p> -All of the above steps -- concretizing, mapping to a device color, and color -loading -- are done as late as possible, normally not until the color is -actually needed for painting. - -<p> -All painting operations (fill, stroke, imagemask/show) eventually call a -virtual procedure in the device color, either <code>fill_rectangle</code> -or <code>fill_mask</code> to actually paint pixels. For rectangle fills, -pure colors call the device's <code>fill_rectangle</code> procedure; -halftones and tiled Patterns call the device's -<code>strip_tile_rectangle</code>; shaded Patterns, and painting operations -that involve a RasterOp, do something more complicated. - -<dl> - -<dt> -Color specification: -<dd> -<a href="../base/gsdcolor.h">base/gsdcolor.h</a>, -<a href="../base/gscolor.c">base/gscolor.c</a>, -<a href="../base/gscolor.h">base/gscolor.h</a>, -<a href="../base/gscolor1.c">base/gscolor1.c</a>, -<a href="../base/gscolor1.h">base/gscolor1.h</a>, -<a href="../base/gscolor2.c">base/gscolor2.c</a>, -<a href="../base/gscolor2.h">base/gscolor2.h</a>, -<a href="../base/gscolor3.c">base/gscolor3.c</a>, -<a href="../base/gscolor3.h">base/gscolor3.h</a>, -<a href="../base/gshsb.c">base/gshsb.c</a>, -<a href="../base/gshsb.h">base/gshsb.h</a>, -<a href="../base/gxcolor2.h">base/gxcolor2.h</a>, -<a href="../base/gxcvalue.h">base/gxcvalue.h</a>. - -<dt> -Color spaces: -<dd> -<a href="../base/gscdevn.c">base/gscdevn.c</a>, -<a href="../base/gscdevn.h">base/gscdevn.h</a>, -<a href="../base/gscie.c">base/gscie.c</a>, -<a href="../base/gscie.h">base/gscie.h</a>, -<a href="../base/gscpixel.c">base/gscpixel.c</a>, -<a href="../base/gscpixel.h">base/gscpixel.h</a>, -<a href="../base/gscscie.c">base/gscscie.c</a>, -<a href="../base/gscsepr.c">base/gscsepr.c</a>, -<a href="../base/gscsepr.h">base/gscsepr.h</a>, -<a href="../base/gscspace.c">base/gscspace.c</a>, -<a href="../base/gscspace.h">base/gscspace.h</a>, -<a href="../base/gscssub.c">base/gscssub.c</a>, -<a href="../base/gscssub.h">base/gscssub.h</a>, -<a href="../base/gxcdevn.h">base/gxcdevn.h</a>, -<a href="../base/gxcie.h">base/gxcie.h</a>, -<a href="../base/gxcspace.h">base/gxcspace.h</a>. - -<dt> -Color mapping: -<dd> -<a href="../base/gsciemap.c">base/gsciemap.c</a>, -<a href="../base/gscindex.h">base/gscindex.h</a>, -<a href="../base/gscrd.c">base/gscrd.c</a>, -<a href="../base/gscrd.h">base/gscrd.h</a>, -<a href="../base/gscrdp.c">base/gscrdp.c</a>, -<a href="../base/gscrdp.h">base/gscrdp.h</a>, -<a href="../base/gscsel.h">base/gscsel.h</a>, -<a href="../base/gxcindex.h">base/gxcindex.h</a>, -<a href="../base/gxcmap.c">base/gxcmap.c</a>, -<a href="../base/gxcmap.h">base/gxcmap.h</a>, -<a href="../base/gxctable.c">base/gxctable.c</a>, -<a href="../base/gxctable.h">base/gxctable.h</a>, -<a href="../base/gxdcconv.c">base/gxdcconv.c</a>, -<a href="../base/gxdcconv.h">base/gxdcconv.h</a>, -<a href="../base/gxdcolor.c">base/gxdcolor.c</a>, -<a href="../base/gxdcolor.h">base/gxdcolor.h</a>, -<a href="../base/gxdevndi.c">base/gxdevndi.c</a>, -<a href="../base/gxdevndi.h">base/gxdevndi.h</a>, -<a href="../base/gxdither.h">base/gxdither.h</a>, -<a href="../base/gxfmap.h">base/gxfmap.h</a>, -<a href="../base/gxlum.h">base/gxlum.h</a>, -<a href="../base/gxtmap.h">base/gxtmap.h</a>. - -<p> -ICC profiles are in some ways a special case of color mapping, but are -not standard in PostScript. - -<dt> -<dd> -<a href="../base/gsicc.c">base/gsicc.c</a>, -<a href="../base/gsicc.h">base/gsicc.h</a>, - -<p> -The following files provide a callback mechanism to allow a client program -to specify a special case alternate tint transforms for Separation and DeviceN -color spaces. Among other uses this can be used to provide special handling for -PANTONE colors. -<dt> -<dd> -<a href="../base/gsnamecl.c">base/gsnamecl.c</a>, -<a href="../base/gsnamecl.h">base/gsnamecl.h</a>, -<a href="../base/gsncdummy.c">base/gsncdummy.c</a>, -<a href="../base/gsncdummy.h">base/gsncdummy.h</a>, -<a href="../psi/zncdummy.c">psi/zncdummy.c</a>, - -</dl> - -<p> -Ghostscript represents halftones internally by "whitening orders" -- -essentially, arrays of arrays of bit coordinates within a halftone cell, -specifying which bits are inverted to get from halftone level K to level -K+1. The code does support all of the PostScript halftone types, but they -are all ultimately reduced to whitening orders. - -<p> -Threshold arrays, the more conventional representation of halftones, can be -mapped to whitening orders straightforwardly; however, whitening orders can -represent non-monotonic halftones (halftones where the bits turned on for -level K+1 don't necessarily include all the bits turned on for level K), -while threshold arrays cannot. On the other hand, threshold arrays allow -rapid conversion of images (using a threshold comparison for each pixel) -with no additional space, while whitening orders do not: they require -storing the rendered halftone cell for each possible level as a bitmap. - -<p> -Ghostscript uses two distinct types of rendered halftones -- that is, the -bitmap(s) that represent a particular level. - -<ul> - -<li>Binary halftones. The rendered halftone is a single bit plane; each bit -selects one of two pure colors. These are fast but limited: they are used -for monochrome output devices, or for color devices in those cases where -only two distinct colors are involved in a halftone (e.g., a pure cyan shade -on a CMYK device). The device color for a binary halftone stores a pointer -to the halftone bitmap, and the two pure colors. - -<li>Multi-plane halftones. Internally, each plane is rendered individually. -Since there isn't enough room to store all 2^N pure colors, multi-plane -halftones only store the scaled values for the individual components; the -halftone renderer maps these to the pure colors on the fly, then combines -the planes to assemble an N-bit index into the list of colors for each -pixel, and stores the color into the fully rendered halftone. - -</ul> - -<p> -The halftone level for rendering a color is computed in <a -href="../base/gxdevndi.c">base/gxdevndi.c</a>; the actual halftone mask or -tile is computed either in <a href="../base/gxcht.c">base/gxcht.c</a> (for -multi-plane halftones), or in <a href="../base/gxht.c">base/gxht.c</a> and <a -href="../base/gxhtbit.c">base/gxhtbit.c</a> (for binary halftones). - -<dl> - -<dt> -Halftoning: -<dd> -<a href="../base/gsht.c">base/gsht.c</a>, -<a href="../base/gsht.h">base/gsht.h</a>, -<a href="../base/gsht1.c">base/gsht1.c</a>, -<a href="../base/gsht1.h">base/gsht1.h</a>, -<a href="../base/gshtscr.c">base/gshtscr.c</a>, -<a href="../base/gshtx.c">base/gshtx.c</a>, -<a href="../base/gshtx.h">base/gshtx.h</a>, -<a href="../base/gxcht.c">base/gxcht.c</a>, -<a href="../base/gxdht.h">base/gxdht.h</a>, -<a href="../base/gxdhtres.h">base/gxdhtres.h</a>, -<a href="../base/gxht.c">base/gxht.c</a>, -<a href="../base/gxht.h">base/gxht.h</a>, -<a href="../base/gxhtbit.c">base/gxhtbit.c</a>, -<a href="../base/gxhttile.h">base/gxhttile.h</a>, -<a href="../base/gxhttype.h">base/gxhttype.h</a>, -<a href="../base/gzht.h">base/gzht.h</a>. - -</dl> - -<p> -Pattern colors (tiled patterns and shadings) each use a slightly different -approach from solid colors. - -<p> -The device color for a tiled (PatternType 1) pattern contains a pointer to a -pattern instance, plus (for uncolored patterns) the device color to be -masked. The pattern instance includes a procedure that actually paints the -pattern if the pattern is not in the cache. For the PostScript interpreter, -this procedure returns an <code>gs_error_RemapColor</code> exception code: this -eventually causes the interpreter to run the pattern's PaintProc, loading -the rendering into the cache, and then re-execute the original drawing -operator. - -<dl> - -<dt> -Patterns: -<dd> -<a href="../base/gspcolor.c">base/gs.color.c</a>, -<a href="../base/gspcolor.h">base/gs.color.h</a>, -<a href="../base/gsptype1.c">base/gsptype1.c</a>, -<a href="../base/gsptype1.h">base/gsptype1.h</a>, -<a href="../base/gxp1fill.c">base/gxp1fill.c</a>, -<a href="../base/gxp1impl.h">base/gxp1impl.h</a>, -<a href="../base/gxpcache.h">base/gxpcache.h</a>, -<a href="../base/gxpcmap.c">base/gxpcmap.c</a>, -<a href="../base/gxpcolor.h">base/gxpcolor.h</a>. - -</dl> - -<p> -The device color for a shading (PatternType 2) pattern also contains a -pointer to a pattern instance. Shadings are not cached: painting with a -shading runs the shading algorithm every time. - -<dl> - -<dt> -Shading: -<dd> -<a href="../base/gsptype2.c">base/gsptype2.c</a>, -<a href="../base/gsptype2.h">base/gsptype2.h</a>, -<a href="../base/gsshade.c">base/gsshade.c</a>, -<a href="../base/gsshade.h">base/gsshade.h</a>, -<a href="../base/gxshade.c">base/gxshade.c</a>, -<a href="../base/gxshade.h">base/gxshade.h</a>, -<a href="../base/gxshade1.c">base/gxshade1.c</a>, -<a href="../base/gxshade4.c">base/gxshade4.c</a>, -<a href="../base/gxshade4.h">base/gxshade4.h</a>, -<a href="../base/gxshade6.c">base/gxshade6.c</a>, -<a href="../base/gscicach.h">base/gscicach.h</a>, -<a href="../base/gscicach.c">base/gscicach.c</a>. - -</dl> - -<p> In addition to the PostScript graphics model, Ghostscript supports RasterOp, - a weak form of alpha channel, and eventually the full PDF 1.4 transparency model. - The implemention of these facilities is quite slipshod and scattered: only RasterOp - is really implemented fully. There is a general compositing architecture, but - it is hardly used at all, and in particular is not used for RasterOp. It is - used for implementation of the general support for overprint and overprint mode. -<dl> - -<dt> -Compositing architecture: -<dd> -<a href="../base/gscompt.h">base/gscompt.h</a>, -<a href="../base/gxcomp.h">base/gxcomp.h</a>. - -<dt> -RasterOp: -<dd> -<a href="../base/gdevdrop.c">base/gdevdrop.c</a>, -<a href="../base/gdevrops.c">base/gdevrops.c</a>, -<a href="../base/gsrop.c">base/gsrop.c</a>, -<a href="../base/gsrop.h">base/gsrop.h</a>, -<a href="../base/gsropt.h">base/gsropt.h</a>, -<a href="../base/gsroptab.c">base/gsroptab.c</a>, -<a href="../base/gxdevrop.h">base/gxdevrop.h</a>. - -<dt> -Alpha channel and compositing: -<dd> -<a href="../base/gsalpha.c">base/gsalpha.c</a>, -<a href="../base/gsalpha.h">base/gsalpha.h</a>, -<a href="../base/gsdpnext.h">base/gsdpnext.h</a>, -<a href="../base/gxalpha.h">base/gxalpha.h</a>. - -<dt> -Advanced transparency: -<dd> -<a href="../base/gstparam.h">base/gstparam.h</a>, -<a href="../base/gstrans.c">base/gstrans.c</a>, -<a href="../base/gstrans.h">base/gstrans.h</a>, -<a href="../base/gxblend.c">base/gxblend.c</a>, -<a href="../base/gxblend.h">base/gxblend.h</a>, -<a href="../base/gdevp14.c">base/gdevp14.c</a>, -<a href="../base/gdevp14.h">base/gdevp14.h</a>. - -<dt> -Overprint and Overprint mode: -<dd> -<a href="../base/gsovrc.c">base/gsovrc.c</a>, -<a href="../base/gsovrc.h">base/gsovrc.h</a>, -<a href="../base/gxoprect.c">base/gxoprect.c</a>, -<a href="../base/gxoprect.h">base/gxoprect.h</a>. -There is support for both overprint and overprint mode. There is a general -compositor based implementation of these features for all devices. In addition, -the memory devices implement a higher speed set of special fill routines to -improve performance for printer based devices. - -</dl> - -<h4><a name="Clipping"></a>Clipping</h4> - -<p> -The Ghostscript graphics library implements clipping by inserting a clipping -device in the device pipeline. The clipping device modifies all drawing -operations to confine them to the clipping region. - -<p> -The library supports three different kinds of clipping: - -<dl> - -<dt> -Region/path clipping -<dd> -This corresponds to the PostScript concept of a clipping path. The clipping -region is specified either by a list of rectangles (subject to the -constraints documented in <a href="../base/gxcpath.h">base/gxcpath.h</a>), or -by a path that is converted to such a list of rectangles. - -<dt> -Stationary mask clipping -<dd> -This corresponds to the mask operand of a PostScript ImageType 3 image. The -clipping region is specified by a bitmap and an (X,Y) offset in the -coordinate space. - -<dt> -Tiled mask clipping -<dd> -This corresponds to the region painted by a PostScript Pattern, for the case -where the Pattern does not completely cover its bounding box but the -combined transformation matrix has no skew or non-orthogonal rotation (i.e., -XStep and YStep map respectively to (X,0) and (0,Y) or vice versa). The -clipping region is specified by a bitmap and an (X,Y) offset in the -coordinate space, and is replicated indefinitely in both X and Y. - -</dl> - -<p> -Note that simply scan-converting a clipping path in the usual way does not -produce a succession of rectangles that can simply be stored as the list for -region-based clipping: in general, the rectangles do not satisfy the -constraint for rectangle lists specified in <a -href="../base/gxcpath.h">base/gxcpath.h</a>, since they may overlap in X, Y, -or both. A non-trivial "clipping list accumulator" device is needed to -produce a rectangle list that does satisfy the constraint. - -<dl> - -<dt> -Clipping support: -<dd> -<a href="../base/gxclip.c">base/gxclip.c</a>, -<a href="../base/gxclip.h">base/gxclip.h</a>. - -<dt> -Region/path clipping: -<dd> -<a href="../base/gxcpath.c">base/gxcpath.c</a>, -<a href="../base/gxcpath.h">base/gxcpath.h</a>, -<a href="../base/gzcpath.h">base/gzcpath.h</a>. - -<dt> -Clipping list accumulator: -<dd> -<a href="../base/gxacpath.c">base/gxacpath.c</a>, -<a href="../base/gzacpath.h">base/gzacpath.h</a>. - -<dt> -Mask clipping support: -<dd> -<a href="../base/gxmclip.c">base/gxmclip.c</a>, -<a href="../base/gxmclip.h">base/gxmclip.h</a>. - -<dt> -Stationary mask clipping: -<dd> -<a href="../base/gxclipm.c">base/gxclipm.c</a>, -<a href="../base/gxclipm.h">base/gxclipm.h</a>. - -<dt> -Tiled mask clipping: -<dd> -<a href="../base/gxclip2.c">base/gxclip2.c</a>, -<a href="../base/gxclip2.h">base/gxclip2.h</a>. - -</dl> - -<h4><a name="Other_graphics"></a>Other graphics</h4> - -<dl> - -<dt> -Miscellaneous graphics state: -<dd> -<a href="../base/gsclipsr.c">base/gsclipsr.c</a>, -<a href="../base/gsclipsr.h">base/gsclipsr.h</a>, -<a href="../base/gsdps.c">base/gsdps.c</a>, -<a href="../base/gsdps.h">base/gsdps.h</a>, -<a href="../base/gsdps1.c">base/gsdps1.c</a>, -<a href="../base/gsistate.c">base/gsistate.c</a>, -<a href="../base/gsline.c">base/gsline.c</a>, -<a href="../base/gsline.h">base/gsline.h</a>, -<a href="../base/gslparam.h">base/gslparam.h</a>, -<a href="../base/gsstate.c">base/gsstate.c</a>, -<a href="../base/gsstate.h">base/gsstate.h</a>, -<a href="../base/gstrap.c">base/gstrap.c</a>, -<a href="../base/gstrap.h">base/gstrap.h</a>, -<a href="../base/gxclipsr.h">base/gxclipsr.h</a>, -<a href="../base/gxistate.h">base/gxistate.h</a>, -<a href="../base/gxline.h">base/gxline.h</a>, -<a href="../base/gxstate.h">base/gxstate.h</a>, -<a href="../base/gzline.h">base/gzline.h</a>, -<a href="../base/gzstate.h">base/gzstate.h</a>. - -</dl> - -<h4><a name="FAPI_support_gx"></a>Font API support</h4> - -<dl> - -<dt> -UFST bridge: -<dd> -<a href="../base/gxfapiu.c">base/gxfapiu.c</a>, -<a href="../base/gxfapiu.h">base/gxfapiu.h</a>. -</dl> - - -<h4><a name="Driver_support"></a>Driver support</h4> - -<dl> - -<dt> -Generic driver support: -<dd> -<a href="../base/gdevdcrd.c">base/gdevdcrd.c</a>, -<a href="../base/gdevdcrd.h">base/gdevdcrd.h</a>, -<a href="../base/gdevdsha.c">base/gdevdsha.c</a>, -<a href="../base/gdevemap.c">base/gdevemap.c</a>, -<a href="../base/gsdevice.c">base/gsdevice.c</a>, -<a href="../base/gsdevice.h">base/gsdevice.h</a>, -<a href="../base/gsdparam.c">base/gsdparam.c</a>, -<a href="../base/gsxfont.h">base/gsxfont.h</a>, -<a href="../base/gxdevbuf.h">base/gxdevbuf.h</a>, -<a href="../base/gxdevcli.h">base/gxdevcli.h</a>, -<a href="../base/gxdevice.h">base/gxdevice.h</a>, -<a href="../base/gxrplane.h">base/gxrplane.h</a>, -<a href="../base/gxxfont.h">base/gxxfont.h</a>. - -<dt> -Accessing rendered bits: -<dd> -<a href="../base/gdevdbit.c">base/gdevdbit.c</a>, -<a href="../base/gdevdgbr.c">base/gdevdgbr.c</a>, -<a href="../base/gxbitfmt.h">base/gxbitfmt.h</a>, -<a href="../base/gxgetbit.h">base/gxgetbit.h</a>. - -<dt> -"Printer" driver support: -<dd> -<a href="../devices/gdevmeds.c">devices/gdevmeds.c</a>, -<a href="../devices/gdevmeds.h">devices/gdevmeds.h</a>, -<a href="../base/gdevppla.c">base/gdevppla.c</a>, -<a href="../base/gdevppla.h">base/gdevppla.h</a>, -<a href="../base/gdevprn.c">base/gdevprn.c</a>, -<a href="../base/gdevprn.h">base/gdevprn.h</a>, -<a href="../base/gdevprna.c">base/gdevprna.c</a>, -<a href="../base/gdevprna.h">base/gdevprna.h</a>, -<a href="../base/gxband.h">base/gxband.h</a>, -<a href="../base/gxpageq.c">base/gxpageq.c</a>, -<a href="../base/gxpageq.h">base/gxpageq.h</a>. - -<dt> -High-level device support: -<dd> -<a href="../base/gdevvec.c">base/gdevvec.c</a>, -<a href="../base/gdevvec.h">base/gdevvec.h</a>, -<a href="../base/gxhldevc.c">base/gxhldevc.c</a>, -<a href="../base/gxhldevc.h">base/gxhldevc.h</a>. - -<dt> -Banding: -<dd> -<a href="../base/gxclbits.c">base/gxclbits.c</a>, -<a href="../base/gxcldev.h">base/gxcldev.h</a>, -<a href="../base/gxclfile.c">base/gxclfile.c</a>, -<a href="../base/gxclimag.c">base/gxclimag.c</a>, -<a href="../base/gxclio.h">base/gxclio.h</a>, -<a href="../base/gxclist.c">base/gxclist.c</a>, -<a href="../base/gxclist.h">base/gxclist.h</a>, -<a href="../base/gxcllzw.c">base/gxcllzw.c</a>, -<a href="../base/gxclmem.c">base/gxclmem.c</a>, -<a href="../base/gxclmem.h">base/gxclmem.h</a>, -<a href="../base/gxclpage.c">base/gxclpage.c</a>, -<a href="../base/gxclpage.h">base/gxclpage.h</a>, -<a href="../base/gxclpath.c">base/gxclpath.c</a>, -<a href="../base/gxclpath.h">base/gxclpath.h</a>, -<a href="../base/gxclrast.c">base/gxclrast.c</a>, -<a href="../base/gxclread.c">base/gxclread.c</a>, -<a href="../base/gxclrect.c">base/gxclrect.c</a>, -<a href="../base/gxclthrd.c">base/gxclthrd.c</a>, -<a href="../base/gxclthrd.h">base/gxclthrd.h</a>, -<a href="../base/gxclutil.c">base/gxclutil.c</a>, -<a href="../base/gxclzlib.c">base/gxclzlib.c</a>, -<a href="../base/gxdhtserial.c">base/gxdhtserial.c</a>, -<a href="../base/gxdhtserial.h">base/gxdhtserial.h</a>, -<a href="../base/gsserial.c">base/gsserial.c</a>, -<a href="../base/gsserial.h">base/gsserial.h</a>. - -</dl> - -<h4><a name="Visual_trace"></a>Visual Trace</h4> - -<dl> - -<dt> -Visual Trace support : -<dd> -<a href="../base/vdtrace.h">base/vdtrace.h</a>, -<a href="../base/vdtrace.c">base/vdtrace.c</a>. -</dl> - -See <a href="Lib.htm">doc/Lib.htm</a> for extensive documentation on -Visual Trace instructions. - - -<h3><a name="Device_drivers"></a>Device drivers</h3> - -<p> -See <a href="Drivers.htm">doc/Drivers.htm</a> for extensive documentation on -the interface between the core code and drivers. - -<p> -The driver API includes high-level (path / image / text), mid-level -(polygon), and low-level (rectangle / raster) operations. Most devices -implement only the low-level operations, and let generic code break down the -high-level operations. However, some devices produce high-level output, and -therefore must implement the high-level operations. - -<h4><a name="Internal_devices"></a>Internal devices</h4> - -<p> -There are a number of "devices" that serve internal purposes. Some of these -are meant to be real rendering targets; others are intended for use in -device pipelines. The rendering targets are: - -<dl> - -<dt> -Memory devices, depth-independent: -<dd> -<a href="../base/gdevmem.c">base/gdevmem.c</a>, -<a href="../base/gdevmem.h">base/gdevmem.h</a>, -<a href="../base/gdevmpla.c">base/gdevmpla.c</a>, -<a href="../base/gdevmpla.h">base/gdevmpla.h</a>, -<a href="../base/gdevmrop.h">base/gdevmrop.h</a>, -<a href="../base/gsdevmem.c">base/gsdevmem.c</a>, -<a href="../base/gxdevmem.h">base/gxdevmem.h</a>. - -<dt> -Memory devices, specific depths: -<dd> -<a href="../base/gdevm1.c">base/gdevm1.c</a>, -<a href="../base/gdevm2.c">base/gdevm2.c</a>, -<a href="../base/gdevm4.c">base/gdevm4.c</a>, -<a href="../base/gdevm8.c">base/gdevm8.c</a>, -<a href="../base/gdevm16.c">base/gdevm16.c</a>, -<a href="../base/gdevm24.c">base/gdevm24.c</a>, -<a href="../base/gdevm32.c">base/gdevm32.c</a>, -<a href="../base/gdevm40.c">base/gdevm40.c</a>, -<a href="../base/gdevm48.c">base/gdevm48.c</a>, -<a href="../base/gdevm56.c">base/gdevm56.c</a>, -<a href="../base/gdevm64.c">base/gdevm64.c</a>, -<a href="../base/gdevmr1.c">base/gdevmr1.c</a>, -<a href="../base/gdevmr2n.c">base/gdevmr2n.c</a>, -<a href="../base/gdevmr8n.c">base/gdevmr8n.c</a>. - -<dt> -Alpha-related devices: -<dd> -<a href="../base/gdevabuf.c">base/gdevabuf.c</a>. - -<dt> -Other devices: -<dd> -<a href="../base/gdevdflt.c">base/gdevdflt.c</a>, -<a href="../base/gdevhit.c">base/gdevhit.c</a>, -<a href="../base/gdevmrun.c">base/gdevmrun.c</a>, -<a href="../base/gdevmrun.h">base/gdevmrun.h</a>, -<a href="../base/gdevplnx.c">base/gdevplnx.c</a>, -<a href="../base/gdevplnx.h">base/gdevplnx.h</a>. -</dl> - -<p> -The forwarding devices meant for use in pipelines are: - -<dl> - -<dt> -The bounding box device: -<dd> -<a href="../base/gdevbbox.h">base/gdevbbox.h</a>, -<a href="../base/gdevbbox.c">base/gdevbbox.c</a>. - -<dt> -Clipping devices: -<dd> -See under <a href="#Clipping">Clipping</a> above. - -<dt> -Other devices: -<dd> -<a href="../base/gdevnfwd.c">base/gdevnfwd.c</a>. - -</dl> - -<h4><a name="PS_and_PDF_writers"></a>PostScript and PDF writers</h4> - -<p> -Because PostScript and PDF have the same graphics model, lexical syntax, and -stack-based execution model, the drivers that produce PostScript and PDF -output share a significant amount of support code. In the future, the -PostScript output driver should be replaced with a slightly modified version -of the PDF driver, since the latter is far more sophisticated (in -particular, it has extensive facilities for image compression and for -handling text and fonts). - -<p> -The PDF code for handling text and fonts is complex and fragile. A major -rewrite in June 2002 was intended to make it more robust and somewhat easier -to understand, but also increased its size by about 40%, contrary to the -expectation that it would shrink. Currently both sets of code are in the -code base, with compatible APIs, selected by a line in <a -href="../devices/devs.mak">devices/devs.mak</a>. - -<dl> - -<dt> -Shared support: -<dd> - -<dl> - <dt> - Writing fonts:</dt> - <dd> - <a href="../devices/vector/gdevpsf.h">devices/vector/gdevpsf.h</a>, - <a href="../devices/vector/gdevpsf1.c">devices/vector/gdevpsf1.c</a>, - <a href="../devices/vector/gdevpsf2.c">devices/vector/gdevpsf2.c</a>, - <a href="../devices/vector/gdevpsfm.c">devices/vector/gdevpsfm.c</a>, - <a href="../devices/vector/gdevpsft.c">devices/vector/gdevpsft.c</a>, - <a href="../devices/vector/gdevpsfu.c">devices/vector/gdevpsfu.c</a>, - <a href="../devices/vector/gdevpsfx.c">devices/vector/gdevpsfx.c</a>, - <a href="../base/gscedata.c">base/gscedata.c</a>, - <a href="../base/gscedata.h">base/gscedata.h</a>, - <a href="../base/gscencs.c">base/gscencs.c</a>, - <a href="../base/gscencs.h">base/gscencs.h</a>. - - <dt> - Other:</dt> - <dd> - <a href="../devices/vector/gdevpsdf.h">devices/vector/gdevpsdf.h</a>, - <a href="../devices/vector/gdevpsdi.c">devices/vector/gdevpsdi.c</a>, - <a href="../devices/vector/gdevpsdp.c">devices/vector/gdevpsdp.c</a>, - <a href="../devices/vector/gdevpsds.c">devices/vector/gdevpsds.c</a>, - <a href="../devices/vector/gdevpsds.h">devices/vector/gdevpsds.h</a>, - <a href="../devices/vector/gdevpsdu.c">devices/vector/gdevpsdu.c</a>. - -</dl> - -<dl> -<dt> -Encapsulated PostScript output driver (epswrite):</dt> -<dd> -<a href="../devices/vector/gdevpsu.c">devices/vector/gdevpsu.c</a>, -<a href="../devices/vector/gdevpsu.h">devices/vector/gdevpsu.h</a>. -</dd> -</dl> - -<dl> -<dt> -PDF output driver (pdfwrite):</dt> -<dd></dd> -</dl> - -<dl> - -<dt> -Substrate:</dt> -<dd> -<a href="../devices/vector/gdevpdfo.c">devices/vector/gdevpdfo.c</a>, -<a href="../devices/vector/gdevpdfo.h">devices/vector/gdevpdfo.h</a>, -<a href="../devices/vector/gdevpdfr.c">devices/vector/gdevpdfr.c</a>, -<a href="../devices/vector/gdevpdfu.c">devices/vector/gdevpdfu.c</a>. -</dd> -</dl> - -<dl> -<dt> -Old text and fonts:</dt> -<dd> -<a href="../devices/vector/gdevpdfe.c">devices/vector/gdevpdfe.c</a>, -<a href="../devices/vector/gdevpdft.c">devices/vector/gdevpdft.c</a>. -</dd> -</dl> - - -<dl> -<dt> -New text and fonts:</dt> -<dd> -<a href="../devices/vector/gdevpdt.c">devices/vector/gdevpdt.c</a>, -<a href="../devices/vector/gdevpdt.h">devices/vector/gdevpdt.h</a>, -<a href="../devices/vector/gdevpdtb.c">devices/vector/gdevpdtb.c</a>, -<a href="../devices/vector/gdevpdtb.h">devices/vector/gdevpdtb.h</a>, -<a href="../devices/vector/gdevpdtc.c">devices/vector/gdevpdtc.c</a>, -<a href="../devices/vector/gdevpdtd.c">devices/vector/gdevpdtd.c</a>, -<a href="../devices/vector/gdevpdtd.h">devices/vector/gdevpdtd.h</a>, -<a href="../devices/vector/gdevpdte.c">devices/vector/gdevpdte.c</a>, -<a href="../devices/vector/gdevpdtf.c">devices/vector/gdevpdtf.c</a>, -<a href="../devices/vector/gdevpdtf.h">devices/vector/gdevpdtf.h</a>, -<a href="../devices/vector/gdevpdti.c">devices/vector/gdevpdti.c</a>, -<a href="../devices/vector/gdevpdti.h">devices/vector/gdevpdti.h</a>, -<a href="../devices/vector/gdevpdts.c">devices/vector/gdevpdts.c</a>, -<a href="../devices/vector/gdevpdts.h">devices/vector/gdevpdts.h</a>, -<a href="../devices/vector/gdevpdtt.c">devices/vector/gdevpdtt.c</a>, -<a href="../devices/vector/gdevpdtt.h">devices/vector/gdevpdtt.h</a>, -<a href="../devices/vector/gdevpdtv.c">devices/vector/gdevpdtv.c</a>, -<a href="../devices/vector/gdevpdtv.h">devices/vector/gdevpdtv.h</a>, -<a href="../devices/vector/gdevpdtw.c">devices/vector/gdevpdtw.c</a>, -<a href="../devices/vector/gdevpdtw.h">devices/vector/gdevpdtw.h</a>, -<a href="../devices/vector/gdevpdtx.h">devices/vector/gdevpdtx.h</a>. -<a href="../base/ConvertUTF.h">base/ConvertUTF.h</a>, -<a href="../base/ConvertUTF.c">base/ConvertUTF.c</a>, -</dd> -</dl> - -<dl> -<dt> -Graphics:</dt> -<dd> -<a href="../devices/vector/gdevpdfc.c">devices/vector/gdevpdfc.c</a>, -<a href="../devices/vector/gdevpdfc.h">devices/vector/gdevpdfc.h</a>, -<a href="../devices/vector/gdevpdfd.c">devices/vector/gdevpdfd.c</a>, -<a href="../devices/vector/gdevpdfg.c">devices/vector/gdevpdfg.c</a>, -<a href="../devices/vector/gdevpdfg.h">devices/vector/gdevpdfg.h</a>, -<a href="../devices/vector/gdevpdfk.c">devices/vector/gdevpdfk.c</a>, -<a href="../devices/vector/gdevpdft.c">devices/vector/gdevpdft.c</a>. -<a href="../devices/vector/gdevpdfv.c">devices/vector/gdevpdfv.c</a>. -</dd> -</dl> - -<dl> -<dt> -Images:</dt> -<dd> -<a href="../devices/vector/gdevpdfb.c">devices/vector/gdevpdfb.c</a>, -<a href="../devices/vector/gdevpdfi.c">devices/vector/gdevpdfi.c</a>, -<a href="../devices/vector/gdevpdfj.c">devices/vector/gdevpdfj.c</a>. -</dd> -</dl> - -<dl> -<dt> -Other:</dt> -<dd> -<a href="../devices/vector/gdevpdf.c">devices/vector/gdevpdf.c</a>, -<a href="../devices/vector/gdevpdfm.c">devices/vector/gdevpdfm.c</a>, -<a href="../devices/vector/gdevpdfp.c">devices/vector/gdevpdfp.c</a>, -<a href="../devices/vector/gdevpdfx.h">devices/vector/gdevpdfx.h</a>. -<a href="../devices/vector/gdevpdfb.h">devices/vector/gdevpdfb.h</a>. -</dd> - -</dl> - - - -<h4><a name="High_level_devices"></a>Other high-level devices</h4> - -<dl> - <dt> -PCL XL output device (pxlmono, pxlcolor):</dt> -<dd> -<a href="../devices/vector/gdevpx.c">devices/vector/gdevpx.c</a>, -<a href="../base/gdevpxat.h">base/gdevpxat.h</a>, -<a href="../base/gdevpxen.h">base/gdevpxen.h</a>, -<a href="../base/gdevpxop.h">base/gdevpxop.h</a>, -<a href="../devices/gdevpxut.c">devices/gdevpxut.c</a>, -<a href="../devices/gdevpxut.h">devices/gdevpxut.h</a>. -</dd> -</dl> - -<dl> - -<dt> -Text extraction:</dt> -<dd> -<a href="../devices/vector/gdevtxtw.c">devices/vector/gdevtxtw.c</a>. -</dd> -</dl> -<dl> -<dt> -Other high-level devices:</dt> -<dd> -<a href="../devices/gdevtrac.c">devices/gdevtrac.c</a>. -</dd> -</dl> - - -<h4><a name="Other_maintained_drivers"></a>Other maintained drivers</h4> - -<p> -The standard Ghostscript distribution includes a collection of drivers, -mostly written by Aladdin Enterprises, that are "maintained" in the same -sense as the Ghostscript core code. - -<dl> - -<dt> -Display drivers:</dt> -<dd> -<a href="../devices/gdev8bcm.c">devices/gdev8bcm.c</a>, -<a href="../devices/gdev8bcm.h">devices/gdev8bcm.h</a>, -<a href="../devices/gdevevga.c">devices/gdevevga.c</a>, -<a href="../devices/gdevl256.c">devices/gdevl256.c</a>, -<a href="../base/gdevpccm.c">base/gdevpccm.c</a>, -<a href="../base/gdevpccm.h">base/gdevpccm.h</a>, -<a href="../devices/gdevpcfb.c">devices/gdevpcfb.c</a>, -<a href="../devices/gdevpcfb.h">devices/gdevpcfb.h</a>, -<a href="../devices/gdevs3ga.c">devices/gdevs3ga.c</a>, -<a href="../devices/gdevsco.c">devices/gdevsco.c</a>, -<a href="../devices/gdevsvga.c">devices/gdevsvga.c</a>, -<a href="../devices/gdevsvga.h">devices/gdevsvga.h</a>, -<a href="../devices/gdevvglb.c">devices/gdevvglb.c</a>. -</dd> -</dl> - -<dl> -<dt> -Window system drivers:</dt> -<dd></dd> -</dl> - -<dl> - -<dt> -X Windows:</dt> -<dd> -<a href="../devices/gdevx.c">devices/gdevx.c</a>, -<a href="../devices/gdevx.h">devices/gdevx.h</a>, -<a href="../devices/gdevxalt.c">devices/gdevxalt.c</a>, -<a href="../devices/gdevxcmp.c">devices/gdevxcmp.c</a>, -<a href="../devices/gdevxcmp.h">devices/gdevxcmp.h</a>, -<a href="../devices/gdevxini.c">devices/gdevxini.c</a>, -<a href="../devices/gdevxres.c">devices/gdevxres.c</a>. -</dd> -</dl> - -<dl> -<dt> -Microsoft Windows:</dt> -<dd> -<a href="../devices/gdevmswn.c">devices/gdevmswn.c</a>, -<a href="../devices/gdevmswn.h">devices/gdevmswn.h</a>, -<a href="../devices/gdevmsxf.c">devices/gdevmsxf.c</a>, -<a href="../devices/gdevwddb.c">devices/gdevwddb.c</a>, -<a href="../devices/gdevwdib.c">devices/gdevwdib.c</a>.</dd> - -<dt> -OS/2 Presentation Manager:</dt> -<dd> -<a href="../devices/gdevpm.h">devices/gdevpm.h</a>, -<a href="../base/gspmdrv.c">base/gspmdrv.c</a>, -<a href="../base/gspmdrv.h">base/gspmdrv.h</a>.</dd> - -</dl> - -<dl> -<dt> -Raster file output drivers:</dt> -<dd></dd> -</dl> - -<dl> - -<dt> -Fax and TIFF:</dt> -<dd> -<a href="../devices/gdevfax.c">devices/gdevfax.c</a>, -<a href="../devices/gdevfax.h">devices/gdevfax.h</a>, -<a href="../devices/gdevtfax.c">devices/gdevtfax.c</a>, -<a href="../devices/gdevtfax.h">devices/gdevtfax.h</a>, -<a href="../devices/gdevtifs.c">devices/gdevtifs.c</a>, -<a href="../devices/gdevtifs.h">devices/gdevtifs.h</a>, -<a href="../devices/gdevtfnx.c">devices/gdevtfnx.c</a>. -<a href="../devices/gdevtsep.c">devices/gdevtsep.c</a>. - -</dd> - -<dt> -Example DeviceN devices: -<dd> -<a href="../base/gdevdevn.c">base/gdevdevn.c</a>, -<a href="../base/gdevdevn.h">base/gdevdevn.h</a>, -<a href="../devices/gdevxcf.c">devices/gdevxcf.c</a>, -<a href="../devices/gdevpsd.c">devices/gdevpsd.c</a>, -<a href="../devices/gdevperm.c">devices/gdevperm.c</a>. - -</dd> - -<dt> -Other raster file formats: -<dd> -<a href="../devices/gdevbit.c">devices/gdevbit.c</a>, -<a href="../devices/gdevbmp.c">devices/gdevbmp.c</a>, -<a href="../devices/gdevbmp.h">devices/gdevbmp.h</a>, -<a href="../devices/gdevbmpa.c">devices/gdevbmpa.c</a>, -<a href="../devices/gdevbmpc.c">devices/gdevbmpc.c</a>, -<a href="../devices/gdevjpeg.c">devices/gdevjpeg.c</a>, -<a href="../devices/gdevmiff.c">devices/gdevmiff.c</a>, -<a href="../devices/gdevp2up.c">devices/gdevp2up.c</a>, -<a href="../devices/gdevpcx.c">devices/gdevpcx.c</a>, -<a href="../devices/gdevpbm.c">devices/gdevpbm.c</a>, -<a href="../devices/gdevpng.c">devices/gdevpng.c</a>, -<a href="../devices/gdevpsim.c">devices/gdevpsim.c</a>. - -</dd> - -</dl> - -<dl> -<dt> -Printer drivers: -<dd> - -<dl> - -<dt> -Operating system printer services: -<dd> -<a href="../devices/gdevos2p.c">devices/gdevos2p.c</a>, -<a href="../devices/gdevwpr2.c">devices/gdevwpr2.c</a>, -<a href="../devices/gdevwprn.c">devices/gdevwprn.c</a>. - -<dt> -H-P monochrome printers: -<dd> -<a href="../devices/gdevdljm.c">devices/gdevdljm.c</a>, -<a href="../devices/gdevdljm.h">devices/gdevdljm.h</a>, -<a href="../devices/gdevdjet.c">devices/gdevdjet.c</a>, -<a href="../devices/gdevlj56.c">devices/gdevlj56.c</a>. - -<dt> -Other printers: -<dd> -<a href="../devices/gdevatx.c">devices/gdevatx.c</a>. - -</dl> - -</dl> - -<h4><a name="Contributed_drivers"></a>Contributed drivers</h4> - -<p> -This list is likely to be incomplete and inaccurate: see -<a href="../devices/contrib.mak">devices/contrib.mak</a> and -<a href="../contrib/contrib.mak">contrib/contrib.mak</a>. - -<dl> - -<dt> -Display and window system drivers: -<dd> -<a href="../devices/gdev3b1.c">devices/gdev3b1.c</a>, -<a href="../devices/gdevherc.c">devices/gdevherc.c</a>, -<a href="../devices/gdevpe.c">devices/gdevpe.c</a>, -<a href="../devices/gdevsnfb.c">devices/gdevsnfb.c</a>, -<a href="../devices/gdevsun.c">devices/gdevsun.c</a>. - -<dt> -Raster file output drivers: -<dd> -<a href="../devices/gdevcfax.c">devices/gdevcfax.c</a>, -<a href="../devices/gdevcif.c">devices/gdevcif.c</a>, -<a href="../devices/gdevdfax.c">devices/gdevdfax.c</a>, -<a href="../devices/gdevifno.c">devices/gdevifno.c</a>, -<a href="../devices/gdevmgr.c">devices/gdevmgr.c</a>, -<a href="../devices/gdevmgr.h">devices/gdevmgr.h</a>, -<a href="../devices/gdevsgi.c">devices/gdevsgi.c</a>, -<a href="../devices/gdevsgi.h">devices/gdevsgi.h</a>, -<a href="../devices/gdevsunr.c">devices/gdevsunr.c</a>, -<a href="../devices/gdevjbig2.c">devices/gdevjbig2.c</a>, -<a href="../devices/gdevjpx.c">devices/gdevjpx.c</a>. - -<dt> -Printer drivers: -<dd> -<a href="../lib/bj8.rpd">lib/bj8.rpd</a>, -<a href="../lib/cbjc600.ppd">lib/cbjc600.ppd</a>, -<a href="../lib/cbjc800.ppd">lib/cbjc800.ppd</a>, -<a href="../devices/gdev3852.c">devices/gdev3852.c</a>, -<a href="../devices/gdev4081.c">devices/gdev4081.c</a>, -<a href="../devices/gdev4693.c">devices/gdev4693.c</a>, -<a href="../devices/gdev8510.c">devices/gdev8510.c</a>, -<a href="../devices/gdevadmp.c">devices/gdevadmp.c</a>, -<a href="../devices/gdevbj10.c">devices/gdevbj10.c</a>, -<a href="../devices/gdevbjc.h">devices/gdevbjc.h</a>, -<a href="../devices/gdevbjcl.c">devices/gdevbjcl.c</a>, -<a href="../devices/gdevbjcl.h">devices/gdevbjcl.h</a>, -<a href="../devices/gdevccr.c">devices/gdevccr.c</a>, -<a href="../devices/gdevcdj.c">devices/gdevcdj.c</a>, -<a href="../devices/gdevclj.c">devices/gdevclj.c</a>, -<a href="../devices/gdevcljc.c">devices/gdevcljc.c</a>, -<a href="../devices/gdevcslw.c">devices/gdevcslw.c</a>, -<a href="../devices/gdevdjtc.c">devices/gdevdjtc.c</a>, -<a href="../devices/gdevdm24.c">devices/gdevdm24.c</a>, -<a href="../devices/gdevepsc.c">devices/gdevepsc.c</a>, -<a href="../devices/gdevepsn.c">devices/gdevepsn.c</a>, -<a href="../devices/gdevescp.c">devices/gdevescp.c</a>, -<a href="../devices/gdevhl7x.c">devices/gdevhl7x.c</a>, -<a href="../devices/gdevijs.c">devices/gdevijs.c</a>, -<a href="../devices/gdevimgn.c">devices/gdevimgn.c</a>, -<a href="../devices/gdevl31s.c">devices/gdevl31s.c</a>, -<a href="../devices/gdevlbp8.c">devices/gdevlbp8.c</a>, -<a href="../devices/gdevlp8k.c">devices/gdevlp8k.c</a>, -<a href="../devices/gdevlxm.c">devices/gdevlxm.c</a>, -<a href="../devices/gdevn533.c">devices/gdevn533.c</a>, -<a href="../devices/gdevo182.c">devices/gdevo182.c</a>, -<a href="../devices/gdevokii.c">devices/gdevokii.c</a>, -<a href="../devices/gdevpcl.c">devices/gdevpcl.c</a>, -<a href="../devices/gdevpcl.h">devices/gdevpcl.h</a>, -<a href="../devices/gdevphex.c">devices/gdevphex.c</a>, -<a href="../devices/gdevpjet.c">devices/gdevpjet.c</a>, -<a href="../devices/gdevsj48.c">devices/gdevsj48.c</a>, -<a href="../devices/gdevsppr.c">devices/gdevsppr.c</a>, -<a href="../devices/gdevstc.c">devices/gdevstc.c</a>, -<a href="../devices/gdevstc.h">devices/gdevstc.h</a>, -<a href="../devices/gdevstc1.c">devices/gdevstc1.c</a>, -<a href="../devices/gdevstc2.c">devices/gdevstc2.c</a>, -<a href="../devices/gdevstc3.c">devices/gdevstc3.c</a>, -<a href="../devices/gdevstc4.c">devices/gdevstc4.c</a>, -<a href="../devices/gdevtknk.c">devices/gdevtknk.c</a>, -<a href="../devices/gdevupd.c">devices/gdevupd.c</a>. - -<dt> -The special <code>rinkj</code> high-quality inkjet driver: -<dd> -<a href="../devices/gdevrinkj.c">devices/gdevrinkj.c</a>, -<a href="../base/gsequivc.c">base/gsequivc.c</a>, -<a href="../base/gsequivc.h">base/gsequivc.h</a>, -<a href="../devices/rinkj/evenbetter-rll.c">devices/rinkj/evenbetter-rll.c</a>, -<a href="../devices/rinkj/evenbetter-rll.h">devices/rinkj/evenbetter-rll.h</a>, -<a href="../devices/rinkj/rinkj-byte-stream.c">devices/rinkj/rinkj-byte-stream.c</a>, -<a href="../devices/rinkj/rinkj-byte-stream.h">devices/rinkj/rinkj-byte-stream.h</a>, -<a href="../devices/rinkj/rinkj-config.c">devices/rinkj/rinkj-config.c</a>, -<a href="../devices/rinkj/rinkj-config.h">devices/rinkj/rinkj-config.h</a>, -<a href="../devices/rinkj/rinkj-device.c">devices/rinkj/rinkj-device.c</a>, -<a href="../devices/rinkj/rinkj-device.h">devices/rinkj/rinkj-device.h</a>, -<a href="../devices/rinkj/rinkj-dither.c">devices/rinkj/rinkj-dither.c</a>, -<a href="../devices/rinkj/rinkj-dither.h">devices/rinkj/rinkj-dither.h</a>, -<a href="../devices/rinkj/rinkj-epson870.c">devices/rinkj/rinkj-epson870.c</a>, -<a href="../devices/rinkj/rinkj-epson870.h">devices/rinkj/rinkj-epson870.h</a>, -<a href="../devices/rinkj/rinkj-screen-eb.c">devices/rinkj/rinkj-screen-eb.c</a>, -<a href="../devices/rinkj/rinkj-screen-eb.h">devices/rinkj/rinkj-screen-eb.h</a>, -<a href="../lib/rinkj-2200-setup">lib/rinkj-2200-setup</a>. - -</dl> - -<h3><a name="PostScript_interpreter"></a>PostScript interpreter</h3> - -<p> -The PostScript interpreter is conceptually simple: in fact, an interpreter -that could execute "3 4 add =" and print "7" was running 3 weeks after the -first line of Ghostscript code was written. However, a number of -considerations make the code large and complex. - -<p> -The interpreter is designed to run in environments with very limited memory. -The main consequence of this is that it cannot allocate its stacks -(dictionary, execution, operand) as ordinary arrays, since the -user-specified stack size limit may be very large. Instead, it allocates -them as a linked list of blocks. See below for more details. - -<p> -The interpreter must never cause a C runtime error that it cannot trap. -Unfortunately, C implementations almost never provide the ability to trap -stack overflow. In order to put a fixed bound on the C stack size, the -interpreter never implements PostScript recursion by C recursion. This -means that any C code that logically needs to call the interpreter must -instead push a continuation (including all necessary state information) on -the PostScript execution stack, followed by the PostScript object to be -executed, and then <em>return</em> to the interpreter. (See <a -href="../psi/estack.h">psi/estack.h</a> for more details about -continuations.) Unfortunately, since PostScript Level 2 introduces streams -whose data source can be a PostScript procedure, any code that reads or -writes stream data must be prepared to suspend itself, storing all necessary -state in a continuation. There are some places where this is extremely -awkward, such as the scanner/parser. - -<p> -The use of continuations affects many places in the interpreter, and even -some places in the graphics library. For example, when processing an image, -one may need to call a PostScript procedure as part of mapping a CIE color -to a device color. Ghostscript uses a variety of dodges to handle this: for -example, in the case of CIE color mapping, all of the PostScript procedures -are pre-sampled and the results cached. The Adobe implementation limits -this kind of recursion to a fixed number of levels (5?): this would be -another acceptable approach, but at this point it would require far more -code restructuring than it would be worth. - -<p> -A significant amount of the PostScript language implementation is in fact -written in PostScript. Writing in PostScript leverages the C code for -multi-threading, garbage collection, error handling, continuations for -streams, etc., etc.; also, we have found PostScript in general more concise -and easier to debug than C, mostly because of memory management issues. So -given the choice, we tended to implement a feature in PostScript if it -worked primarily with PostScript data structures, wasn't heavily used -(example: font loading), or if it interacted with the stream or other -callback machinery (examples: ReusableFileDecode streams, resourceforall). -Often we would add non-standard PostScript operators for functions that had -to run faster or that did more C-like things, such as the media matching -algorithm for setpagedevice. - - - -<h4><a name="Main_program"></a>Main program</h4> - -<p> -The main program of the interpreter is normally invoked from the command -line, but it has an API as well. In fact, it has two APIs: one that -recognizes the existence of multiple "interpreter instances" (although it -currently provides a default instance, which almost all clients use), and a -completely different one designed for Windows DLLs. These should be unified -as soon as possible, since there are two steadily growing incompatible -bodies of client code. - -<dl> - -<dt> -Files: -<dd> -<a href="../psi/gs.c">psi/gs.c</a>, -<a href="../psi/gserver.c">psi/gserver.c</a>, -<a href="../psi/iinit.c">psi/iinit.c</a>, -<a href="../psi/iinit.h">psi/iinit.h</a>, -<a href="../psi/imain.c">psi/imain.c</a>, -<a href="../psi/imain.h">psi/imain.h</a>, -<a href="../psi/imainarg.c">psi/imainarg.c</a>, -<a href="../psi/imainarg.h">psi/imainarg.h</a>, -<a href="../psi/iminst.h">psi/iminst.h</a>, -<a href="../psi/main.h">psi/main.h</a>. - -</dl> - -<h4><a name="Data_structures"></a>Data structures</h4> - -<p> -The main data structures visible to the PostScript programmers are arrays, -contexts, dictionaries, names, and stacks. - -<p> -Arrays have no unusual properties. See under <a href="#Refs">Refs</a> below -for more information about how array elements are stored. - -<p> -Contexts are used to hold the interpreter state even in configurations that -don't include the Display PostScript multiple context extension. Context -switching is implemented by a complex cooperation of C and PostScript code. - -<p> -Dictionaries have two special properties worth noting: - -<ul> - -<li>They use an optimized storage representation if all the keys are names, -which is almost always the case. - -<li>They interact with a caching scheme used to accelerate name lookup in -the interpreter. - -</ul> - -<p> -Names are allocated in blocks. The characters and hash chains are stored -separately from the lookup cache information, so that in the future, most of -the former can be compiled into the executable and shared or put in ROM. -(This is not actually done yet.) - -<dl> - -<dt> -Contexts: -<dd> -<a href="../psi/icontext.c">psi/icontext.c</a>, -<a href="../psi/icontext.h">psi/icontext.h</a>, -<a href="../psi/icstate.h">psi/icstate.h</a>. - -<dt> -Dictionaries: -<dd> -<a href="../psi/iddict.h">psi/iddict.h</a>, -<a href="../psi/idict.h">psi/idict.h</a>, -<a href="../psi/idict.c">psi/idict.c</a>, -<a href="../psi/idictdef.h">psi/idictdef.h</a>, -<a href="../psi/idicttpl.h">psi/idicttpl.h</a>. - -<dt> -Names: -<dd> -<a href="../psi/iname.c">psi/iname.c</a>, -<a href="../psi/iname.h">psi/iname.h</a>, -<a href="../psi/inamedef.h">psi/inamedef.h</a>, -<a href="../psi/inameidx.h">psi/inameidx.h</a>, -<a href="../psi/inames.h">psi/inames.h</a>, -<a href="../psi/inamestr.h">psi/inamestr.h</a>. - -</dl> - -<h4><a name="Stacks"></a>Stacks</h4> - -<p> -As mentioned above, each stack is allocated as a linked list of blocks. -However, for reasonable performance, operators must normally be able to -access their operands and produce their results using indexing rather than -an access procedure. This is implemented by ensuring that all the operands -of an operator are in the topmost block of the stack, using guard entries -that cause an internal error if the condition isn't met. See <a -href="../psi/iostack.h">psi/iostack.h</a> for more details. - -<dl> - -<dt> -Generic stacks: -<dd> -<a href="../psi/isdata.h">psi/isdata.h</a>, -<a href="../psi/istack.c">psi/istack.c</a>, -<a href="../psi/istack.h">psi/istack.h</a>, -<a href="../psi/istkparm.h">psi/istkparm.h</a>. - -<dt> -Specific stacks: -<dd> - -<dl> - -<dt> -Dictionary stack: -<dd> -<a href="../psi/dstack.h">psi/dstack.h</a>, -<a href="../psi/iddstack.h">psi/iddstack.h</a>, -<a href="../psi/idsdata.h">psi/idsdata.h</a>, -<a href="../psi/idstack.c">psi/idstack.c</a>, -<a href="../psi/idstack.h">psi/idstack.h</a>. - -<dt> -Execution stack: -<dd> -<a href="../psi/estack.h">psi/estack.h</a>, -<a href="../psi/iesdata.h">psi/iesdata.h</a>, -<a href="../psi/iestack.h">psi/iestack.h</a>. - -<dt> -Operand stack: -<dd> -<a href="../psi/iosdata.h">psi/iosdata.h</a>, -<a href="../psi/iostack.h">psi/iostack.h</a>, -<a href="../psi/ostack.h">psi/ostack.h</a>. - -</dl> - -</dl> - -<h4><a name="Interpreter_loop"></a>Interpreter loop</h4> - -<dl> - -<dt> -Files: -<dd> -<a href="../psi/interp.c">psi/interp.c</a>, -<a href="../psi/interp.h">psi/interp.h</a>. - -</dl> - -<h4><a name="Scanning_parsing"></a>Scanning/parsing</h4> - -<p> -PostScript parsing consists essentially of token scanning, and is simple in -principle. The scanner is complex because it must be able to suspend its -operation at any time (i.e., between any two input characters) to allow an -interpreter callout, if its input is coming from a procedure-based stream -and the procedure must be called to provide more input data. - -<dl> - -<dt> -Main scanner: -<dd> -<a href="../psi/iscan.c">psi/iscan.c</a>, -<a href="../psi/iscan.h">psi/iscan.h</a>, -<a href="../psi/iscannum.c">psi/iscannum.c</a>, -<a href="../psi/iscannum.h">psi/iscannum.h</a>, -<a href="../base/scanchar.h">base/scanchar.h</a>, -<a href="../base/scantab.c">base/scantab.c</a>. - -<dt> -Binary tokens: -<dd> -<a href="../psi/btoken.h">psi/btoken.h</a>, -<a href="../psi/ibnum.c">psi/ibnum.c</a>, -<a href="../psi/ibnum.h">psi/ibnum.h</a>, -<a href="../psi/inobtokn.c">psi/inobtokn.c</a>, -<a href="../psi/iscanbin.c">psi/iscanbin.c</a>, -<a href="../psi/iscanbin.h">psi/iscanbin.h</a>. - -<dt> -DSC parsing: -<dd> -<a href="../psi/dscparse.c">psi/dscparse.c</a>, -<a href="../psi/dscparse.h">psi/dscparse.h</a>. - -</dl> - -<h4><a name="Standard_operators"></a>Standard operators</h4> - -<dl> - -<dt> -Non-output-related: -<dd> - -<dl> - -<dt> -Filters: -<dd> -<a href="../psi/ifilter.h">psi/ifilter.h</a>, -<a href="../psi/ifilter2.h">psi/ifilter2.h</a>, -<a href="../psi/ifrpred.h">psi/ifrpred.h</a>, -<a href="../psi/ifwpred.h">psi/ifwpred.h</a>, -<a href="../psi/istream.h">psi/istream.h</a>, -<a href="../psi/zfbcp.c">psi/zfbcp.c</a>, -<a href="../psi/zfdctd.c">psi/zfdctd.c</a>, -<a href="../psi/zfdcte.c">psi/zfdcte.c</a>, -<a href="../psi/zfdecode.c">psi/zfdecode.c</a>, -<a href="../psi/zfilter.c">psi/zfilter.c</a>, -<a href="../psi/zfilter2.c">psi/zfilter2.c</a>, -<a href="../psi/zfjbig2.c">psi/zfjbig2.c</a>, -<a href="../psi/zfjpx.c">psi/zfjpx.c</a>, -<a href="../psi/zfmd5.c">psi/zfmd5.c</a>, -<a href="../psi/zfarc4.c">psi/zfarc4.c</a>, -<a href="../psi/zfproc.c">psi/zfproc.c</a>, -<a href="../psi/zfrsd.c">psi/zfrsd.c</a>, -<a href="../psi/zfzlib.c">psi/zfzlib.c</a>. - -<dt> -File and stream I/O: -<dd> -<a href="../psi/files.h">psi/files.h</a>, -<a href="../psi/itoken.h">psi/itoken.h</a>, -<a href="../psi/zbseq.c">psi/zbseq.c</a>, -<a href="../psi/zdscpars.c">psi/zdscpars.c</a>, -<a href="../psi/zfile.h">psi/zfile.h</a>, -<a href="../psi/zfile.c">psi/zfile.c</a>, -<a href="../psi/zfile1.c">psi/zfile1.c</a>, -<a href="../psi/zfileio.c">psi/zfileio.c</a>, -<a href="../psi/ztoken.c">psi/ztoken.c</a>. - -<dt> -Data structures: -<dd> -<a href="../psi/zarray.c">psi/zarray.c</a>, -<a href="../psi/zdict.c">psi/zdict.c</a>, -<a href="../psi/zgeneric.c">psi/zgeneric.c</a>, -<a href="../psi/zpacked.c">psi/zpacked.c</a>, -<a href="../psi/zstring.c">psi/zstring.c</a>. - -<dt> -Functions: -<dd> -<a href="../psi/ifunc.h">psi/ifunc.h</a>, -<a href="../psi/zfunc.c">psi/zfunc.c</a>, -<a href="../psi/zfunc0.c">psi/zfunc0.c</a>, -<a href="../psi/zfunc3.c">psi/zfunc3.c</a>, -<a href="../psi/zfunc4.c">psi/zfunc4.c</a>, - -<dt> -Other: -<dd> -<a href="../psi/ivmem2.h">psi/ivmem2.h</a>, -<a href="../psi/zalg.c">psi/zalg.c</a>, -<a href="../psi/zarith.c">psi/zarith.c</a>, -<a href="../psi/zcontext.c">psi/zcontext.c</a>, -<a href="../psi/zcontrol.c">psi/zcontrol.c</a>, -<a href="../psi/zmath.c">psi/zmath.c</a>, -<a href="../psi/zmatrix.c">psi/zmatrix.c</a>, -<a href="../psi/zmisc.c">psi/zmisc.c</a>, -<a href="../psi/zmisc1.c">psi/zmisc1.c</a>, -<a href="../psi/zmisc2.c">psi/zmisc2.c</a>, -<a href="../psi/zmisc3.c">psi/zmisc3.c</a>, -<a href="../psi/zrelbit.c">psi/zrelbit.c</a>, -<a href="../psi/zstack.c">psi/zstack.c</a>, -<a href="../psi/ztype.c">psi/ztype.c</a>, -<a href="../psi/zusparam.c">psi/zusparam.c</a>, -<a href="../psi/zvmem.c">psi/zvmem.c</a>, -<a href="../psi/zvmem2.c">psi/zvmem2.c</a>. - -</dl> - -<dt> -Output-related: -<dd> - -<dl> - -<dt> -Device management: -<dd> -<a href="../psi/zdevcal.c">psi/zdevcal.c</a>, -<a href="../psi/zdevice.c">psi/zdevice.c</a>, -<a href="../psi/zdevice2.c">psi/zdevice2.c</a>, -<a href="../psi/ziodev.c">psi/ziodev.c</a>, -<a href="../psi/ziodev2.c">psi/ziodev2.c</a>, -<a href="../psi/ziodevs.c">psi/ziodevs.c</a>, -<a href="../psi/zmedia2.c">psi/zmedia2.c</a>, - -<dt> -Fonts and text: -<dd> -<a href="../psi/bfont.h">psi/bfont.h</a>, -<a href="../psi/ichar.h">psi/ichar.h</a>, -<a href="../psi/ichar1.h">psi/ichar1.h</a>, -<a href="../psi/icharout.h">psi/icharout.h</a>, -<a href="../psi/icid.h">psi/icid.h</a>, -<a href="../psi/ifcid.h">psi/ifcid.h</a>, -<a href="../psi/ifont.h">psi/ifont.h</a>, -<a href="../psi/ifont1.h">psi/ifont1.h</a>, -<a href="../psi/ifont2.h">psi/ifont2.h</a>, -<a href="../psi/ifont42.h">psi/ifont42.h</a>, -<a href="../psi/zbfont.c">psi/zbfont.c</a>, -<a href="../psi/zcfont.c">psi/zcfont.c</a>, -<a href="../psi/zchar.c">psi/zchar.c</a>, -<a href="../psi/zchar1.c">psi/zchar1.c</a>, -<a href="../psi/zchar2.c">psi/zchar2.c</a>, -<a href="../psi/zchar32.c">psi/zchar32.c</a>, -<a href="../psi/zchar42.c">psi/zchar42.c</a>, -<a href="../psi/zchar42.h">psi/zchar42.h</a>, -<a href="../psi/zcharout.c">psi/zcharout.c</a>, -<a href="../psi/zcharx.c">psi/zcharx.c</a>, -<a href="../psi/zcid.c">psi/zcid.c</a>, -<a href="../psi/zfcid.c">psi/zfcid.c</a>, -<a href="../psi/zfcid0.c">psi/zfcid0.c</a>, -<a href="../psi/zfcid1.c">psi/zfcid1.c</a>, -<a href="../psi/zfcmap.c">psi/zfcmap.c</a>, -<a href="../psi/zfont.c">psi/zfont.c</a>, -<a href="../psi/zfont0.c">psi/zfont0.c</a>, -<a href="../psi/zfont1.c">psi/zfont1.c</a>, -<a href="../psi/zfont2.c">psi/zfont2.c</a>, -<a href="../psi/zfont32.c">psi/zfont32.c</a>, -<a href="../psi/zfont42.c">psi/zfont42.c</a>, -<a href="../psi/zfontenum.c">psi/zfontenum.c</a>. - -<dt> -A bridge to the True Type bytecode interpreter: -<dd> -<a href="../base/gxttfb.c">base/gxttfb.c</a>, -<a href="../base/gxttfb.h">base/gxttfb.h</a>, -<a href="../base/ttfoutl.h">base/ttfoutl.h</a>, -<a href="../base/ttfmain.c">base/ttfmain.c</a>, -<a href="../base/ttfmemd.c">base/ttfmemd.c</a>, -<a href="../base/ttfmemd.h">base/ttfmemd.h</a>, -<a href="../base/ttfinp.c">base/ttfinp.c</a>, -<a href="../base/ttfinp.h">base/ttfinp.h</a>. - -<dt> -A reduced True Type bytecode interpreter: -<br><em>(this is based in part on the work of the Freetype Team and incorporates some code from -the -FreeType 1 project)</em> -<dd> -<a href="../base/ttfsfnt.h">base/ttfsfnt.h</a>, -<a href="../base/ttcalc.c">base/ttcalc.c</a>, -<a href="../base/ttcalc.h">base/ttcalc.h</a>, -<a href="../base/ttcommon.h">base/ttcommon.h</a>, -<a href="../base/ttconf.h">base/ttconf.h</a>, -<a href="../base/ttconfig.h">base/ttconfig.h</a>, -<a href="../base/ttinterp.c">base/ttinterp.c</a>, -<a href="../base/ttinterp.h">base/ttinterp.h</a>, -<a href="../base/ttload.c">base/ttload.c</a>, -<a href="../base/ttload.h">base/ttload.h</a>, -<a href="../base/ttmisc.h">base/ttmisc.h</a>, -<a href="../base/ttobjs.c">base/ttobjs.c</a>, -<a href="../base/ttobjs.h">base/ttobjs.h</a>, -<a href="../base/tttables.h">base/tttables.h</a>, -<a href="../base/tttype.h">base/tttype.h</a>, -<a href="../base/tttypes.h">base/tttypes.h</a>. - -<dt> -Color, pattern, and halftone: -<dd> -<a href="../psi/icie.h">psi/icie.h</a>, -<a href="../psi/icolor.h">psi/icolor.h</a>, -<a href="../psi/icremap.h">psi/icremap.h</a>, -<a href="../psi/icsmap.h">psi/icsmap.h</a>, -<a href="../psi/iht.h">psi/iht.h</a>, -<a href="../psi/ipcolor.h">psi/ipcolor.h</a>, -<a href="../psi/zcie.c">psi/zcie.c</a>, -<a href="../psi/zcolor.c">psi/zcolor.c</a>, -<a href="../psi/zcolor1.c">psi/zcolor1.c</a>, -<a href="../psi/zcolor2.c">psi/zcolor2.c</a>, -<a href="../psi/zcolor3.c">psi/zcolor3.c</a>, -<a href="../psi/zcrd.c">psi/zcrd.c</a>, -<a href="../psi/zcsindex.c">psi/zcsindex.c</a>, -<a href="../psi/zcspixel.c">psi/zcspixel.c</a>, -<a href="../psi/zcssepr.c">psi/zcssepr.c</a>, -<a href="../psi/zicc.c">psi/zicc.c</a>, -<a href="../psi/zht.c">psi/zht.c</a>, -<a href="../psi/zht1.c">psi/zht1.c</a>, -<a href="../psi/zht2.h">psi/zht2.h</a>, -<a href="../psi/zht2.c">psi/zht2.c</a>, -<a href="../psi/zpcolor.c">psi/zpcolor.c</a>, -<a href="../psi/zshade.c">psi/zshade.c</a>, -<a href="../psi/ztrans.c">psi/ztrans.c</a>. - -<dt> -Images: -<dd> -<a href="../psi/iimage.h">psi/iimage.h</a>, -<a href="../psi/zimage.c">psi/zimage.c</a>, -<a href="../psi/zimage3.c">psi/zimage3.c</a>, -<a href="../psi/zfimscale.c">psi/zfimscale.c</a>. - -<dt> -Other graphics: -<dd> -<a href="../psi/igstate.h">psi/igstate.h</a>, -<a href="../psi/zdpnext.c">psi/zdpnext.c</a>, -<a href="../psi/zdps.c">psi/zdps.c</a>, -<a href="../psi/zdps1.c">psi/zdps1.c</a>, -<a href="../psi/zgstate.c">psi/zgstate.c</a>, -<a href="../psi/zpaint.c">psi/zpaint.c</a>, -<a href="../psi/zpath.c">psi/zpath.c</a>, -<a href="../psi/zpath1.c">psi/zpath1.c</a>, -<a href="../psi/ztrap.c">psi/ztrap.c</a>, -<a href="../psi/zupath.c">psi/zupath.c</a>. - -</dl> - -<dt> -Operator support: -<dd> -<a href="../psi/oparc.h">psi/oparc.h</a>, -<a href="../psi/opcheck.h">psi/opcheck.h</a>, -<a href="../psi/opdef.h">psi/opdef.h</a>, -<a href="../psi/oper.h">psi/oper.h</a>, -<a href="../psi/opextern.h">psi/opextern.h</a>. - -</dl> - -<h4><a name="Non_standard_operators"></a>Non-standard operators</h4> - -<p> -The interpreter includes many non-standard operators. Most of these provide -some part of the function of a standard operator, so that the standard -operator itself can be implemented in PostScript: these are not of interest -to users, and their function is usually obvious from the way they are used. -However, some non-standard operators provide access to additional, -non-standard facilities that users might want to know about, such as -transparency, RasterOp, and in-memory rendering. These are documented at <a -href="Language.htm#Additional_operators">Language.htm#Additional_operators</a>. - -<p> -We don't document the complete set of non-standard operators here, because -the set changes frequently. However, all non-standard operators are -supposed to have names that begin with '.', so you can find them all by -executing the following (Unix) command: - -<blockquote><pre> -grep '{".[.]' psi/[zi]*.c -</pre></blockquote> - -<p> -In addition to individual non-standard operators implemented in the same -files as standard ones, there are several independent optional packages of -non-standard operators. As with other non-standard operators, the names of -all the operators in these packages begin with '.'. We list those packages -here. - -<dl> - -<dt> -<a href="../psi/zdouble.c">psi/zdouble.c</a> -<dd> -Provides "double" floating point arithmetic, using 8-byte strings to hold -values. Developed under a contract; probably used only by the group that -funded the development. - -<dt> -<a href="../psi/zfsample.c">psi/zfsample.c</a>, -<dd> -Provides a special operator to sample a given function and create a new type 0 function. - -<dt> -<a href="../psi/zsysvm.c">psi/zsysvm.c</a> -<dd> -Provides operators for allocating objects in specific VM spaces, -disregarding the current VM mode. - -</dl> - -<h4><a name="Interpreter_support"></a>Interpreter support</h4> - -<p> -Memory management (refs, GC, save/restore) -- see <a -href="#PostScript_interpreter_extensions">below</a>. - -<dl> -<dt> -Font API : -<dd> -<a href="../psi/ifapi.h">psi/ifapi.h</a>, -<a href="../psi/zfapi.c">psi/zfapi.c</a>, -<a href="../base/fapiufst.c">base/fapiufst.c</a>, -<a href="../base/fapi_ft.c">base/fapi_ft.c</a>, -<a href="../base/wrfont.h">base/wrfont.h</a>, -<a href="../base/wrfont.c">base/wrfont.c</a>, -<a href="../base/write_t1.h">base/write_t1.h</a>, -<a href="../base/write_t1.c">base/write_t1.c</a>, -<a href="../base/write_t2.h">base/write_t2.h</a>, -<a href="../base/write_t2.c">base/write_t2.c</a>, - -<dt> -Miscellaneous support: -<dd> -<a href="../psi/ierrors.h">psi/ierrors.h</a>, -<a href="../base/gserrors.h">base/gserrors.h</a>, -<a href="../psi/ghost.h">psi/ghost.h</a>, -<a href="../psi/iconf.c">psi/iconf.c</a>, -<a href="../psi/iconf.h">psi/iconf.h</a>, -<a href="../psi/idparam.c">psi/idparam.c</a>, -<a href="../psi/idparam.h">psi/idparam.h</a>, -<a href="../psi/ilevel.h">psi/ilevel.h</a>, -<a href="../psi/inouparm.c">psi/inouparm.c</a>, -<a href="../psi/iparam.c">psi/iparam.c</a>, -<a href="../psi/iparam.h">psi/iparam.h</a>, -<a href="../psi/iparray.h">psi/iparray.h</a>, -<a href="../psi/iutil.c">psi/iutil.c</a>, -<a href="../psi/iutil.h">psi/iutil.h</a>, -<a href="../psi/iutil2.c">psi/iutil2.c</a>, -<a href="../psi/iutil2.h">psi/iutil2.h</a>, -<a href="../psi/iplugin.c">psi/iplugin.c</a>, -<a href="../psi/iplugin.h">psi/iplugin.h</a>. - -</dl> - -<h4><a name="PostScript_code"></a>PostScript code</h4> - -<dl> - -<dt> -Initialization and language support: -<dd> - -<dl> - -<dt> -All configurations: -<dd> -<a href="../Resource/Init/gs_init.ps">Resource/Init/gs_init.ps</a>, -<a href="../Resource/Init/gs_statd.ps">Resource/Init/gs_statd.ps</a>. - -<dt> -Level 2: -<dd> -<a href="../Resource/Init/gs_btokn.ps">Resource/Init/gs_btokn.ps</a>, -<a href="../Resource/Init/gs_dps1.ps">Resource/Init/gs_dps1.ps</a>, -<a href="../Resource/Init/gs_dps2.ps">Resource/Init/gs_dps2.ps</a>, -<a href="../Resource/Init/gs_lev2.ps">Resource/Init/gs_lev2.ps</a>, -<a href="../Resource/Init/gs_res.ps">Resource/Init/gs_res.ps</a>, -<a href="../Resource/Init/gs_resmp.ps">Resource/Init/gs_resmp.ps</a>, -<a href="../Resource/Init/gs_setpd.ps">Resource/Init/gs_setpd.ps</a>. - -<dt> -LanguageLevel 3: -<dd> -<a href="../Resource/Init/gs_frsd.ps">Resource/Init/gs_frsd.ps</a>, -<a href="../Resource/Init/gs_ll3.ps">Resource/Init/gs_ll3.ps</a>, -<a href="../Resource/Init/gs_trap.ps">Resource/Init/gs_trap.ps</a>. - -<dt> -Display PostScript: -<dd> -<a href="../Resource/Init/gs_dpnxt.ps">Resource/Init/gs_dpnxt.ps</a>, -<a href="../Resource/Init/gs_dps.ps">Resource/Init/gs_dps.ps</a>. - -<dt> -Emulation of other interpreters: -<dd> -<a href="../Resource/Init/gs_cet.ps">Resource/Init/gs_cet.ps</a> (Adobe CPSI). - -</dl> - -<dt> -Color Spaces and support: -<dd> - -<dl> - -<dt> -Color Space Loading: -<dd> -<a href="../Resource/Init/gs_cspace.ps">Resource/Init/gs_cspace.ps</a>, - -<dt> -ICC color profiles: -<dd> -<a href="../Resource/Init/gs_icc.ps">Resource/Init/gs_icc.ps</a>. - -</dl> - -<dt> -Font loading and support: -<dd> - -<dl> - -<dt> -Font name mapping: -<dd> -<a href="../Resource/Init/Fontmap">Resource/Init/Fontmap</a>, -<a href="../lib/Fontmap.ATB">lib/Fontmap.ATB</a>, -<a href="../lib/Fontmap.ATM">lib/Fontmap.ATM</a>, -<a href="../Resource/Init/Fontmap.GS">Resource/Init/Fontmap.GS</a>, -<a href="../lib/Fontmap.OS2">lib/Fontmap.OS2</a>, -<a href="../lib/Fontmap.OSF">lib/Fontmap.OSF</a>, -<a href="../lib/Fontmap.SGI">lib/Fontmap.SGI</a>, -<a href="../lib/Fontmap.Sol">lib/Fontmap.Sol</a>, -<a href="../lib/Fontmap.Ult">lib/Fontmap.Ult</a>, -<a href="../lib/Fontmap.VMS">lib/Fontmap.VMS</a>, -<a href="../lib/Fontmap.URW-136.T1">lib/Fontmap.URW-136.T1</a>, -<a href="../lib/Fontmap.URW-136.TT">lib/Fontmap.URW-136.TT</a>, -<a href="../Resource/Init/cidfmap">Resource/Init/cidfmap</a>, -<a href="../Resource/Init/FAPIcidfmap">Resource/Init/FAPIcidfmap</a>, -<a href="../Resource/Init/FAPIfontmap">Resource/Init/FAPIfontmap</a>, -<a href="../Resource/Init/FCOfontmap-PCLPS2">Resource/Init/FCOfontmap-PCLPS2</a>. - -<dt> -Generic: -<dd> -<a href="../Resource/Init/gs_fonts.ps">Resource/Init/gs_fonts.ps</a>, -<a href="../Resource/Init/gs_fntem.ps">Resource/Init/gs_fntem.ps</a>. - -<dt> -Type 1 and CFF: -<dd> -<a href="../Resource/Init/gs_cff.ps">Resource/Init/gs_cff.ps</a>, -<a href="../Resource/Init/gs_diskf.ps">Resource/Init/gs_diskf.ps</a>, -<a href="../Resource/Init/gs_type1.ps">Resource/Init/gs_type1.ps</a>. - -<dt> -TrueType: -<dd> -<a href="../Resource/Init/gs_ttf.ps">Resource/Init/gs_ttf.ps</a>, -<a href="../Resource/Init/gs_typ42.ps">Resource/Init/gs_typ42.ps</a>. - -<dt> -CID-keyed: -<dd> -<a href="../Resource/Init/gs_cidcm.ps">Resource/Init/gs_cidcm.ps</a>, -<a href="../Resource/Init/gs_cidfn.ps">Resource/Init/gs_cidfn.ps</a>, -<a href="../Resource/Init/gs_cmap.ps">Resource/Init/gs_cmap.ps</a>, -<a href="../Resource/Init/gs_ciddc.ps">Resource/Init/gs_ciddc.ps</a>, -<a href="../Resource/Init/gs_cidfm.ps">Resource/Init/gs_cidfm.ps</a>, -<a href="../Resource/Init/gs_cidtt.ps">Resource/Init/gs_cidtt.ps</a>. - -<dt> -Font API: -<dd> -<a href="../Resource/Init/gs_fapi.ps">Resource/Init/gs_fapi.ps</a>, -<a href="../Resource/Init/FAPIconfig">Resource/Init/FAPIconfig</a>, -<a href="../lib/FAPIconfig-FCO">lib/FAPIconfig-FCO</a>, -<a href="../Resource/Init/xlatmap">Resource/Init/xlatmap</a>. -<a href="../Resource/Init/FCOfontmap-PCLPS2">Resource/Init/FCOfontmap-PCLPS2</a>. -<a href="../lib/FCOfontmap-PCLPS3">lib/FCOfontmap-PCLPS3</a>. -<a href="../lib/FCOfontmap-PS3">lib/FCOfontmap-PS3</a>. - -<dt> -Other: -<dd> -<a href="../lib/gs_kanji.ps">lib/gs_kanji.ps</a>, -<a href="../lib/gs_pfile.ps">lib/gs_pfile.ps</a>, -<a href="../Resource/Init/gs_typ32.ps">Resource/Init/gs_typ32.ps</a>. - -</dl> - -<dt> -Encodings: -<dd> - -<dl> - -<dt> -Adobe-specified: -<dd> -<a href="../lib/gs_ce_e.ps">lib/gs_ce_e.ps</a>, -<a href="../Resource/Init/gs_dbt_e.ps">Resource/Init/gs_dbt_e.ps</a>, -<a href="../Resource/Init/gs_il1_e.ps">Resource/Init/gs_il1_e.ps</a>, -<a href="../Resource/Init/gs_mex_e.ps">Resource/Init/gs_mex_e.ps</a>, -<a href="../Resource/Init/gs_mro_e.ps">Resource/Init/gs_mro_e.ps</a>, -<a href="../Resource/Init/gs_pdf_e.ps">Resource/Init/gs_pdf_e.ps</a>, -<a href="../Resource/Init/gs_std_e.ps">Resource/Init/gs_std_e.ps</a>, -<a href="../Resource/Init/gs_sym_e.ps">Resource/Init/gs_sym_e.ps</a>, -<a href="../Resource/Init/gs_wan_e.ps">Resource/Init/gs_wan_e.ps</a>. - -<dt> -Additional: -<dd> -<a href="../lib/gs_il2_e.ps">lib/gs_il2_e.ps</a>, -<a href="../lib/gs_ksb_e.ps">lib/gs_ksb_e.ps</a>, -<a href="../lib/gs_wl1_e.ps">lib/gs_wl1_e.ps</a>, -<a href="../lib/gs_wl2_e.ps">lib/gs_wl2_e.ps</a>, -<a href="../lib/gs_wl5_e.ps">lib/gs_wl5_e.ps</a>. - -<dt> -Pseudo-encodings for internal use: -<dd> -<a href="../lib/gs_lgo_e.ps">lib/gs_lgo_e.ps</a>, -<a href="../lib/gs_lgx_e.ps">lib/gs_lgx_e.ps</a>, -<a href="../Resource/Init/gs_mgl_e.ps">Resource/Init/gs_mgl_e.ps</a>. - -</dl> - -<dt> -Miscellaneous: -<dd> - -<dl> - -<dt> -Image support: -<dd> -<a href="../Resource/Init/gs_img.ps">Resource/Init/gs_img.ps</a>, - -<dt> -Emulation of %disk IODevice: -<dd> -<a href="../Resource/Init/gs_diskn.ps">Resource/Init/gs_diskn.ps</a>, - -<dt> -Other support: -<dd> -<a href="../Resource/Init/gs_agl.ps">Resource/Init/gs_agl.ps</a>, -<a href="../Resource/Init/gs_dscp.ps">Resource/Init/gs_dscp.ps</a>, -<a href="../Resource/Init/gs_epsf.ps">Resource/Init/gs_epsf.ps</a>, -<a href="../Resource/Init/gs_pdfwr.ps">Resource/Init/gs_pdfwr.ps</a>, -<a href="../lib/gs_rdlin.ps">lib/gs_rdlin.ps</a>. - -<dt> -X Windows icon bitmaps: -<dd> -<a href="../lib/gs_l.xbm">lib/gs_l.xbm</a>, -<a href="../lib/gs_l.xpm">lib/gs_l.xpm</a>, -<a href="../lib/gs_l_m.xbm">lib/gs_l_m.xbm</a>, -<a href="../lib/gs_m.xbm">lib/gs_m.xbm</a>, -<a href="../lib/gs_m.xpm">lib/gs_m.xpm</a>, -<a href="../lib/gs_m_m.xbm">lib/gs_m_m.xbm</a>, -<a href="../lib/gs_s.xbm">lib/gs_s.xbm</a>, -<a href="../lib/gs_s.xpm">lib/gs_s.xpm</a>, -<a href="../lib/gs_s_m.xbm">lib/gs_s_m.xbm</a>, -<a href="../lib/gs_t.xbm">lib/gs_t.xbm</a>, -<a href="../lib/gs_t.xpm">lib/gs_t.xpm</a>, -<a href="../lib/gs_t_m.xbm">lib/gs_t_m.xbm</a>. - -<dt> -PDF/X-3 definition file sample : -<dd> -<a href="../lib/PDFX_def.ps">lib/PDFX_def.ps</a>, - -</dl> - -</dl> - -<h3><a name="PDF_interpreter"></a>PDF interpreter</h3> - -<p> -Ghostscript's PDF interpreter is written entirely in PostScript, because its -data structures are the same as PostScript's, and it is much more convenient -to manipulate PostScript-like data structures in PostScript than in C. -There is definitely a performance cost, but apparently not a substantial -one: we considered moving the main interpreter loop (read a token using -slightly different syntax than PostScript, push it on the stack if literal, -look it up in a special dictionary for execution if not) into C, but we did -some profiling and discovered that this wasn't accounting for enough of the -time to be worthwhile. - -<p> -Until recently, there was essentially no C code specifically for the purpose -of supporting PDF interpretation. The one major exception is the PDF 1.4 -transparency features, which we (but not Adobe) have made available to -PostScript code. - -<p> -In addition to patching the <code>run</code> operator to detect PDF -files, the interpreter provides some procedures in <a -href="../Resource/Init/pdf_main.ps">Resource/Init/pdf_main.ps</a> that are meant to be called -from applications such as previewers. - -<dl> - -<dt> -Files: -<dd> -<a href="../Resource/Init/pdf_base.ps">Resource/Init/pdf_base.ps</a>, -<a href="../Resource/Init/pdf_draw.ps">Resource/Init/pdf_draw.ps</a>, -<a href="../Resource/Init/pdf_font.ps">Resource/Init/pdf_font.ps</a>, -<a href="../Resource/Init/pdf_main.ps">Resource/Init/pdf_main.ps</a>, -<a href="../Resource/Init/pdf_rbld.ps">Resource/Init/pdf_rbld.ps</a>, -<a href="../Resource/Init/pdf_ops.ps">Resource/Init/pdf_ops.ps</a>, -<a href="../Resource/Init/pdf_sec.ps">Resource/Init/pdf_sec.ps</a>. -</dl> - -<h3><a name="PPD"></a>PostScript Printer Description</h3> -<p> -A PostScript Printer Description tells a generic PostScript printer -driver how to generate PostScript for a particular printer. -Ghostscript includes a PPD file for generating PostScript -intended to be converted to PDF. A Windows INF file for -installing the PPD on Windows 2000 and XP is included. - -<dl> - -<dt> -Files: -<dd> -<a href="../lib/ghostpdf.ppd">lib/ghostpdf.ppd</a>, -<a href="../lib/ghostpdf.inf">lib/ghostpdf.inf</a>, -<a href="../lib/ghostpdf.cat">lib/ghostpdf.cat</a>, -<a href="../lib/ghostpdf.README">lib/ghostpdf.README</a>. - -</dl> - -<h3><a name="Build_process"></a>Build process</h3> - -<h4><a name="Makefile_structure"></a>Makefile structure</h4> - -<p> -Ghostscript's makefiles embody a number of design decisions and assumptions -that may not be obvious from a casual reading of the code. - -<ul> - -<li>All files are stored in subdirectories. The names of all subdirectories -used in the build process are defined in the top-level makefiles for the -various platforms: there are no "hard wired" directory names in any makefile -rule. Subdirectory names in the makefiles are relative to the directory -that is current at build time: normally this directory is the parent of the -various subdirectories, and holds only a <code>makefile</code>, which in -turn simply references the real top-level makefile in the source -subdirectory. - -<li>All compiler and linker switches are likewise defined by macros, again -preferably in the top-level platform makefile. - -<li>There is an absolute distinction between "source-like" subdirectories, -which are read-only during the build process, and "object-like" -subdirectories, all of whose contents are generated by the build process and -which can be emptied (<code>rm *</code>) at any time with no bad -effects. The source subdirectories are defined by macros named -<code>xxxSRCDIR</code>. - -<li>Object subdirectories may distinguish further between those that hold -the results of the build process that are needed at run time (i.e., that -should be included in a run-time distribution), defined by -<code>BINDIR</code>, and those that are not needed at run time, defined -by <code>xxxGENDIR</code> and <code>xxxOBJDIR</code>. (The -distinction between these is historical and probably no longer relevant.) - -<li>There may be multiple object subdirectories for different build -configurations. On Unix, the <code>obj</code> and <code>bin</code> -directories are used for normal production builds, the -<code>debugobj</code> directory for debugging builds, and the -<code>pgobj</code> directory for profiling builds; other platforms may -use different conventions. The Unix makefiles support targets named -<code>debug</code> and <code>pg</code> for debugging and profiling -builds respectively; other platforms generally do not. - -<li>Makefiles will be maintained by hand. This requires editing the -following makefile elements whenever the relevant source files changes: - -<ul> - -<li>Every header (.h) file must have a corresponding macro definition in a -makefile. If <code>abc.h</code> #includes <code>def.h</code> and -<code>xyz.h</code>, the definition must have the form - -<blockquote><pre> -xyz_h=$(xxxSRCD)xyz.h $(def_h) $(xyz_h) -</pre></blockquote> - -where <code>xxxSRCD</code> is the macro defining the relevant source -directory (including a trailing '/'). Note that the '.' in the file name -has been replaced by an underscore. Note also that the definition must -follow all definitions it references, since some <code>make</code> -programs expand macros in definitions at the time of definition rather than -at the time of use. - -<li>Every .c file must have a corresponding rule in a makefile. If -<code>abc.c</code> #includes <code>def.h</code> and -<code>lmn.h</code>, the rule must have approximately the form - -<blockquote><pre> -$(xxxOBJD)abc.$(OBJ) : $(xxxSRCD)abc.c $(def_h) $(lmn_h) - $(xxCC) $(xxO_)abc.$(OBJ) $(C_) $(xxxSRCD)abc.c -</pre></blockquote> - -where <code>xxxSRCD</code> is as before; <code>xxxOBJD</code> is the -relevant object directory; <code>xxCC</code> defines the name of the C -compiler plus the relevant compilation switches; and <code>xxO_</code> -and <code>C_</code> are macros used to bridge syntactic differences -between different <code>make</code> programs. - -</ul> - -</ul> - -<p> -The requirement to keep makefiles up to date by hand has been controversial. -Two alternatives are generally proposed. - -<ul> - -<li>Programs like <code>makedeps</code>, which generate build rules -automatically from the #include lists in C files. We have found such -programs useless: they "wire in" specific, concrete directory names, not -only for our own code but even for the system header files; they have to be -run manually whenever code files are added, renamed, or deleted, or whenever -the list of #includes in any file changes; and they cannot deal with -different source files requiring different compilation switches. - -<li>MSVC-style "project" files. These are equally useless: they are not -portable across different vendors' tools -- in fact, there may not even be a -usable import/export facility to convert their data to or from text form -- -and they cannot combine configuration-independent data with -configuration-specific data. - -</ul> - -<p> -We have seriously considered writing our own build program in Tcl or Python -that would eliminate these problems, or perhaps porting the tools developed -by Digital's Vesta research project (if we can get access to them); however, -either of these approaches would create potential portability problems of -its own, not to mention difficulties in integrating with others' build -systems. - -<p> -For more information about makefiles: - -<ul> - -<li>For a detailed list of makefiles, and a discussion of makefile issues -related to portability, see the <a href="#Makefiles">Makefiles</a> section -below. - -<li>For more detailed information about editing configuration information in -makefiles, see <a -href="Make.htm#Makefile_overview">doc/Make.htm#Makefile_overview</a>. - -<li>For a complete example of adding a new driver to a makefile, see <a -href="Drivers.htm#Adding_drivers">doc/Drivers.htm#Adding_drivers</a>. - -<li>For a few more notes on makefile coding conventions, see <a -href="C-style.htm#Makefiles">doc/C-style.htm#Makefiles</a>. - -</ul> - -<h4><a name="dev_files"></a>.dev files</h4> - -<p> -On top of the general conventions just described, Ghostscript's makefiles -add a further layer of structure in order to support an open-ended set of -fine-grained, flexible configuration options. Selecting an option (usually -called a "module") for inclusion in the build may affect the build in many -ways: - -<ul> - -<li>Almost always, it requires linking in some compiled code files. - -<li>It may require running some additional initialization procedures at -startup. - -<li>It may require reading in some additional PostScript files at startup. -For example, a Level 2 PostScript build requires support for PostScript -resources and for setpagedevice, which are implemented in PostScript code. - -<li>It may require adding entries to a variety of internal tables that -catalogue such things as drivers, IODevices, Function types, etc. - -<li>It may require that other particular modules be included. For example, -the "PostScript Level 2" module requires the modules for various filters, -color spaces, etc. - -<li>It may require <em>removing</em> some other (default) module from the -build. For example, the core (Level 1) PostScript build has a "stub" for -binary tokens, which are a Level 2 feature but are referenced by the core -scanner: a Level 2 build must remove the stub. For more information about -this, look for the string <code>-replace</code> in the makefiles and in -<a href="../base/genconf.c">base/genconf.c</a>. - -</ul> - -<p> -Each module is defined in the makefiles by rules that create a file named -<code><em>xxx</em>.dev</code>. The dependencies of the rule include all -the files that make up the module (compiled code files, PostScript files, -etc.); the body of the rule creates the .dev file by writing the description -of the module into it. A program called <code>genconf</code>, described -in the next section, merges all the relevant .dev files together. For -examples of .dev rules, see any of the Ghostscript makefiles. - -<p> -Ultimately, a person must specify the root set of modules to include in a -build (which of course may require other modules, recursively). -Ghostscript's makefiles do this with a set of macros called -<code>FEATURE_DEVS</code> and <code>DEVICE_DEVS</code><em>n</em>, -defined in each top-level makefile, but nothing in the module machinery -depends on this. - -<h4><a name="Generators"></a>Generators</h4> - -<p> -Ghostscript's build procedure is somewhat unusual in that it compiles and -then executes some support programs during the build process. These -programs then generate data or source code that is used later on in the -build. - -<p> -The most important and complex of the generator programs is -<code>genconf</code>. <code>genconf</code> merges all the .dev files -that make up the build, and creates three or more output files used in later -stages: - -<ul> - -<li><code>gconfig.h</code>, consisting mainly of macro calls, one call -per "resource" making up the build, other than "resources" listed in the -other output files. - -<li><code>gconfigf.h</code>, produced only for PostScript builds with -compiled-in fonts, consisting of one macro call per font. - -<li>A linker control file whose name varies from one platform to another, -containing the list of compiled code files to be linked. - -<li>If necessary, another linker control file, also varying between -platforms, that contains other information for the linker such as the list -of system libraries to be searched. (On Unix platforms, the two linker -control functions are combined in a single file.) - -</ul> - -<dl> - -<dt> -Source generators: -<dd> - -<dl> - -<dt> -<a href="../base/genarch.c">base/genarch.c</a> -<dd> -Creates a header file containing a variety of information about the hardware -and compiler that isn't provided in any standard system header file. Always -used. - -<dt> -<a href="../base/genconf.c">base/genconf.c</a> (also generates non-source) -<dd> -Constructs header files and linker control files from the collection of -options and modules that make up the build. See above. Always used. - -<dt> -<a href="../base/genht.c">base/genht.c</a> -<dd> -Converts a PostScript halftone (in a particular constrained format) to a C -data structure that can be compiled into an executable. Only used if any -such halftones are included in the build. - -<dt> -<a href="../base/mkromfs.c">base/mkromfs.c</a> -<dd> -Takes a set of directories, and creates a compressed filesystem -image that can be compiled into the executable as static data and accessed -through the %rom% iodevice prefix. This is used to implement the -<code>COMPILE_INITS=1</code> feature (a compressed init fileset is more -efficient than the current 'gsinit.c' produced by 'geninit.c'). This IODevice -is more versatile since other files can be encapsulated such as fonts, helper -PostScript files and Resources. The list of files is defined in part in -<a href="../psi/psromfs.mak">psi/psromfs.mak</a>. - -</dl> - -<dt> -Other generators: -<dd> - -<dl> - -<dt> -<a href="../base/echogs.c">base/echogs.c</a> -<dd> -Implements a variety of shell-like functions to get around quirks, -limitations, and omissions in the shells on various platforms. Always used. - -<dt> -<a href="../base/genconf.c">base/genconf.c</a> (also generates source) -<dd> -See above. - -<dt> -<a href="../base/gendev.c">base/gendev.c</a> (not used) -<dd> -Was intended as a replacement for <code>genconf</code>, but was never -completed. - -</dl> - -</dl> - -<h4><a name="Build_support"></a>Support</h4> - -<p> -There are a number of programs, scripts, and configuration files that exist -only for the sake of the build process. - -<dl> - -<dt> -Files for PC environments: -<dd> -<a href="../base/gswin.icx">base/gswin.icx</a>, -<a href="../base/gswin16.icx">base/gswin16.icx</a>, -<a href="../base/bcc32.cfg">base/bcc32.cfg</a>, -<a href="../base/cp.bat">base/cp.bat</a>, -<a href="../base/cp.cmd">base/cp.cmd</a>, -<a href="../psi/dw32c.def">psi/dw32c.def</a>, -<a href="../psi/dwmain.rc">psi/dwmain.rc</a>, -<a href="../psi/dwmain32.def">psi/dwmain32.def</a>, -<a href="../psi/dwsetup.def">psi/dwsetup.def</a>, -<a href="../psi/dwsetup_x86.manifest">psi/dwsetup_x86.manifest</a>, -<a href="../psi/dwsetup_x64.manifest">psi/dwsetup_x64.manifest</a>, -<a href="../psi/dwuninst.def">psi/dwuninst.def</a>, -<a href="../psi/dwuninst_x86.manifest">psi/dwuninst_x86.manifest</a>, -<a href="../psi/dwuninst_x64.manifest">psi/dwuninst_x64.manifest</a>, -<a href="../psi/gsdll2.def">psi/gsdll2.def</a>, -<a href="../psi/gsdll2.rc">psi/gsdll2.rc</a>, -<a href="../psi/gsdll32.def">psi/gsdll32.def</a>, -<a href="../psi/gsdll32.rc">psi/gsdll32.rc</a>, -<a href="../psi/gsdll32w.lnk">psi/gsdll32w.lnk</a>, -<a href="../psi/gsos2.def">psi/gsos2.def</a>, -<a href="../psi/gsos2.icx">psi/gsos2.icx</a>, -<a href="../psi/gsos2.rc">psi/gsos2.rc</a>, -<a href="../base/gspmdrv.def">base/gspmdrv.def</a>, -<a href="../base/gspmdrv.icx">base/gspmdrv.icx</a>, -<a href="../base/gspmdrv.rc">base/gspmdrv.rc</a>, -<a href="../base/gswin.rc">base/gswin.rc</a>, -<a href="../base/gswin32.rc">base/gswin32.rc</a>, -<a href="../base/mv.bat">base/mv.bat</a>, -<a href="../base/mv.cmd">base/mv.cmd</a>, -<a href="../base/rm.bat">base/rm.bat</a>, -<a href="../base/rm.cmd">base/rm.cmd</a>, - -<dt> -Files for MacOS: -<dd> -<a href="../lib/Info-macos.plist">lib/Info-macos.plist</a>. - -<dt> -Files for OpenVMS: -<dd> -<a href="../base/append_l.com">base/append_l.com</a>, -<a href="../base/copy_one.com">base/copy_one.com</a>, -<a href="../base/rm_all.com">base/rm_all.com</a>, -<a href="../base/rm_one.com">base/rm_one.com</a>. - -<dt> -Other files: -<dd> -<a href="../base/bench.c">base/bench.c</a>, -<a href="../base/catmake">base/catmake</a>, -<a href="../base/instcopy">base/instcopy</a>. - -</dl> - -<h3><a name="Utilities"></a>Utilities</h3> - -<p> -Ghostscript comes with many utilities for doing things like viewing bitmap -files and converting between file formats. Some of these are written in -PostScript, some as scripts, and some as scripts that invoke special -PostScript code. - -<h4><a name="Utilities_in_PostScript"></a>Utilities in PostScript</h4> - -<p> -These are all documented in <a href="Psfiles.htm">doc/Psfiles.htm</a>, q.v. - -<h4><a name="Utility_scripts"></a>Utility scripts</h4> - -<p> -Many of these scripts come in both Unix and MS-DOS (<code>.bat</code> -versions; some also have an OS/2 (<code>.cmd</code>) version. The choice -of which versions are provided is historical and irregular. These scripts -should all be documented somewhere, but currently, many of them have man -pages, a few have their own documentation in the doc directory, and some -aren't documented at all. - -<dl> - -<dt> -Script files without PC versions: -<dd> -<a href="../lib/afmdiff.awk">lib/afmdiff.awk</a>, -<a href="../lib/dvipdf">lib/dvipdf</a>, -<a href="../lib/lprsetup.sh">lib/lprsetup.sh</a>, -<a href="../lib/pphs">lib/pphs</a>, -<a href="../lib/printafm">lib/printafm</a>, -<a href="../lib/unix-lpr.sh">lib/unix-lpr.sh</a>, -<a href="../lib/wftopfa">lib/wftopfa</a>. - -<dt> -Script files with PC versions: -<dd> -<a href="../lib/eps2eps">lib/eps2eps</a>, -<a href="../lib/eps2eps.bat">lib/eps2eps.bat</a>, -<a href="../lib/eps2eps.cmd">lib/eps2eps.cmd</a>, -<a href="../lib/ps2ps2">lib/ps2ps2</a>, -<a href="../lib/ps2ps2.bat">lib/ps2ps2.bat</a>, -<a href="../lib/ps2ps2.cmd">lib/ps2ps2.cmd</a>, -<a href="../lib/font2c">lib/font2c</a>, -<a href="../lib/font2c.bat">lib/font2c.bat</a>, -<a href="../lib/font2c.cmd">lib/font2c.cmd</a>, -<a href="../lib/gsbj">lib/gsbj</a>, -<a href="../lib/gsbj.bat">lib/gsbj.bat</a>, -<a href="../lib/gsdj">lib/gsdj</a>, -<a href="../lib/gsdj.bat">lib/gsdj.bat</a>, -<a href="../lib/gsdj500">lib/gsdj500</a>, -<a href="../lib/gsdj500.bat">lib/gsdj500.bat</a>, -<a href="../lib/gslj">lib/gslj</a>, -<a href="../lib/gslj.bat">lib/gslj.bat</a>, -<a href="../lib/gslp">lib/gslp</a>, -<a href="../lib/gslp.bat">lib/gslp.bat</a>, -<a href="../lib/gsnd">lib/gsnd</a>, -<a href="../lib/gsnd.bat">lib/gsnd.bat</a>, -<a href="../lib/pdf2dsc">lib/pdf2dsc</a>, -<a href="../lib/pdf2dsc.bat">lib/pdf2dsc.bat</a>, -<a href="../lib/pdf2ps">lib/pdf2ps</a>, -<a href="../lib/pdf2ps.bat">lib/pdf2ps.bat</a>, -<a href="../lib/pdf2ps.cmd">lib/pdf2ps.cmd</a>, -<a href="../lib/pf2afm">lib/pf2afm</a>, -<a href="../lib/pf2afm.bat">lib/pf2afm.bat</a>, -<a href="../lib/pf2afm.cmd">lib/pf2afm.cmd</a>, -<a href="../lib/pfbtopfa">lib/pfbtopfa</a>, -<a href="../lib/pfbtopfa.bat">lib/pfbtopfa.bat</a>, -<a href="../lib/ps2ascii">lib/ps2ascii</a>, -<a href="../lib/ps2ascii.bat">lib/ps2ascii.bat</a>, -<a href="../lib/ps2ascii.cmd">lib/ps2ascii.cmd</a>, -<a href="../lib/ps2epsi">lib/ps2epsi</a>, -<a href="../lib/ps2epsi.bat">lib/ps2epsi.bat</a>, -<a href="../lib/ps2epsi.cmd">lib/ps2epsi.cmd</a>, -<a href="../lib/ps2pdf">lib/ps2pdf</a>, -<a href="../lib/ps2pdf.bat">lib/ps2pdf.bat</a>, -<a href="../lib/ps2pdf.cmd">lib/ps2pdf.cmd</a>, -<a href="../lib/ps2pdf12">lib/ps2pdf12</a>, -<a href="../lib/ps2pdf12.bat">lib/ps2pdf12.bat</a>, -<a href="../lib/ps2pdf12.cmd">lib/ps2pdf12.cmd</a>, -<a href="../lib/ps2pdf13">lib/ps2pdf13</a>, -<a href="../lib/ps2pdf13.bat">lib/ps2pdf13.bat</a>, -<a href="../lib/ps2pdf13.cmd">lib/ps2pdf13.cmd</a>, -<a href="../lib/ps2pdf14">lib/ps2pdf14</a>, -<a href="../lib/ps2pdf14.bat">lib/ps2pdf14.bat</a>, -<a href="../lib/ps2pdf14.cmd">lib/ps2pdf14.cmd</a>, -<a href="../lib/ps2pdfwr">lib/ps2pdfwr</a>, -<a href="../lib/ps2pdfxx.bat">lib/ps2pdfxx.bat</a>, -<a href="../lib/ps2ps">lib/ps2ps</a>, -<a href="../lib/ps2ps.bat">lib/ps2ps.bat</a>, -<a href="../lib/ps2ps.cmd">lib/ps2ps.cmd</a>. - -<dt> -Script files with only PC versions: -<dd> -<a href="../lib/gsndt.bat">lib/gsndt.bat</a>, -<a href="../lib/gssetgs.bat">lib/gssetgs.bat</a>, -<a href="../lib/gssetgs32.bat">lib/gssetgs32.bat</a>, -<a href="../lib/gssetgs64.bat">lib/gssetgs64.bat</a>, -<a href="../lib/gst.bat">lib/gst.bat</a>, -<a href="../lib/gstt.bat">lib/gstt.bat</a>, -<a href="../lib/lp386.bat">lib/lp386.bat</a>, -<a href="../lib/lp386r2.bat">lib/lp386r2.bat</a>, -<a href="../lib/lpgs.bat">lib/lpgs.bat</a>, -<a href="../lib/lpr2.bat">lib/lpr2.bat</a>, -<a href="../lib/pftogsf.bat">lib/pftogsf.bat</a>, -<a href="../lib/wmakebat.bat">lib/wmakebat.bat</a>. - -</dl> - -<hr> - -<h2><a name="Memory_management"></a>Memory management</h2> - -<h3><a name="Memory_manager_architecture"></a>Memory manager architecture</h3> - -<p> -In many environments, the memory manager is a set of library facilities that -implicitly manage the entire address space in a homogenous manner. -Ghostscript's memory manager architecture has none of these properties: - -<ul> - -<li>Rather than a single library accessed as procedures, Ghostscript -includes multiple allocator types, each of which in turn may have multiple -instances (allocators). Allocators are 'objects' with a substantial set of -virtual functions. - -<li>Rather than managing the entire address space, each allocator manages a -storage pool, which it may or may not be able to expand or reduce by calling -on a 'parent' allocator. - -<li>Rather than a single genus of untyped storage blocks, Ghostscript's -allocators provide two genera -- type-tagged 'objects', and 'strings' -- -with substantially different properties. - -</ul> - -<h4><a name="Objects_vs_strings"></a>Objects vs strings</h4> - -<p> -As noted above, allocators provide two different storage genera. - -<p> -Objects: - -<ul> -<li>Are aligned in storage to satisfy the most stringent alignment -requirement imposed by the CPU or compiler; -<li>Can be referenced only by pointers to their start, not to any internal -location, unless special arrangements are made; -<li>May contain pointers to other objects, or to strings; -<li>Have an associated <em>structure descriptor</em> that specifies their -size (usually) and the location of any pointers contained within them. -</ul> - -<p> -Given a pointer to an object, the allocator that allocated it must be able -to return the object's size and the pointer to its structure descriptor. -(It is up to the client to know what allocator allocated an object.) - -<p> -Strings: - -<ul> -<li>Are not aligned in storage; -<li>Can be referenced by pointers (consisting of a starting address and a -length) to any substring, starting anywhere within the string; -<li>May not contain pointers; -<li>Do not have a structure descriptor. -</ul> - -<p> -The object/string distinction reflects a space/capability tradeoff. The -per-object space overhead of the standard type of allocator is typically 12 -bytes; this is too much to impose on every string of a few bytes. On the -other hand, restricting object pointers to reference the start of the object -currently makes object garbage collection and compaction more -space-efficient. If we were to redesign the standard allocator, we would -probably opt for a different design in which strings were allocated within -container objects of a few hundred bytes, and pointers into the middle of -all objects were allowed. - -<h4><a name="Structure_descriptors"></a>Structure descriptors</h4> - -<p> -Every object allocated by a Ghostscript allocator has an associated -structure descriptor, which the caller provides when allocating the object. -The structure descriptor serves several purposes: - -<ul> -<li>Specifying the size of the object for allocation; -<li>Providing pointer-enumeration and pointer-relocation procedures for -the garbage collector; -<li>Providing an optional finalization procedure to be called when the -object is freed (either explicitly or automatically). -</ul> - -<p> -Structure descriptors are read-only, and are normally defined statically -using one of the large set of <code>gs_private_st_</code> or -<code>gs_public_st_</code> macros in <a -href="../base/gsstruct.h">base/gsstruct.h</a>. - -<p> -While the structure descriptor normally specifies the size of the object, -one can also allocate an array of bytes or objects, whose size is a multiple -of the size in the descriptor. For this reason, every object stores its -size as well as a reference to its descriptor. - -<p> -Because the standard Ghostscript garbage collector is non-conservative and -can move objects, every object allocated by a Ghostscript allocator must -have an accurate structure descriptor. If you define a new type of object -(structure) that will be allocated in storage managed by Ghostscript, you -<em>must</em> create an accurate descriptor for it, and use that descriptor -to allocate it. The process of creating accurate descriptors for all -structures was long and painful, and accounted for many hard-to-diagnose -bugs. - -<p> -By convention, the structure descriptor for structure type -<code>xxx_t</code> is named <code>st_xxx</code> (this is preferred), -or occasionally <code>st_xxx_t</code>. - -<p> -Note that a structure descriptor is only required for objects allocated by -the Ghostscript allocator. A structure type <code>xxx_t</code> does not -require a structure descriptor if instances of that type are used -<em>only</em> in the following ways: - -<ul> - -<li>Instances are allocated only on the C stack, e.g., as -<code>xxx_t xxx1, xxx2;</code>, or on the C heap, with -<code>malloc</code> or through the Ghostscript "wrapper" defined in <a -href="../base/gsmalloc.h">base/gsmalloc.h</a>. - -<li>Pointers to instances are not stored in places where the garbage -collector will try to trace the pointer. - -<li>Code never attempts to get the structure type or size of an instance -through the allocator API. - -</ul> - -<p> -In general, structures without descriptors are problem-prone, and are -deprecated; in new code, they should only be used if the structure is -confined to a single .c file and its instances are only allocated on the C -stack. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsstruct.h">base/gsstruct.h</a>, -<a href="../base/gsstype.h">base/gsstype.h</a>. -</dl> - -<h4><a name="Garbage_collection"></a>Garbage collection</h4> - -<p> -The allocator architecture is designed to support compacting garbage -collection. Every object must be able to enumerate all the pointers it -contains, both for tracing and for relocation. As noted just above, the -structure descriptor provides procedures that do this. - -<p> -Whether or not a particular allocator type actually provides a garbage -collector is up to the allocator: garbage collection is invoked through a -virtual procedure. In practice, however, there are only two useful garbage -collectors for Ghostscript's own allocator: - -<ul> -<li>The "real" garbage collector associated with the PostScript interpreter, -described <a href="#Interpreter_GC">below</a>; -<li>A "non" garbage collector that only merges adjacent free blocks. -</ul> - -<p> -As noted above, because the architecture supports compacting garbage -collection, a "real" garbage collector cannot be run at arbitrary times, -because it cannot reliably find and relocate pointers that are on the C -stack. In general, it is only safe to run a "real" garbage collector when -control is at the top level of the program, when there are no pointers to -garbage collectable objects from the stack (other than designated roots). - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsgc.h">base/gsgc.h</a>, -<a href="../base/gsnogc.c">base/gsnogc.c</a>, -<a href="../base/gsnogc.h">base/gsnogc.h</a>. -</dl> - -<h4><a name="Movability"></a>Movability</h4> - -<p> -As just noted, objects are normally movable by the garbage collector. -However, some objects must be immovable, usually because some other piece of -software must retain pointers to them. The allocator API includes -procedures for allocating both movable (default) and immovable objects. -Note, however, that even immovable objects must be traceable (have a -structure descriptor), and may be freed, by the garbage collector. - -<h4><a name="Parent_hierarchy"></a>Parent hierarchy</h4> - -<p> -When an allocator needs to add memory to the pool that it manages, it -requests the memory from its <em>parent</em> allocator. Every allocator has -a pointer to its parent; multiple allocators may share a single parent. The -ultimate ancestor of all allocators that can expand their pool dynamically -is an allocator that calls <code>malloc</code>, described <a -href="#malloc">below</a>. However, especially in embedded environments, an -allocator may be limited to a fixed-size pool assigned to it when it is -created. - -<h4><a name="Allocator_API"></a>Allocator API</h4> - -In summary, the allocator API provides the following principal operations: - -<ul> -<li>Allocate and free movable (default) or immovable objects and strings. -<li>Return the structure type and size of an object. -<li>Resize (shrink or grow) movable objects and strings, preserving -the contents insofar as possible. -<li>Report the size of the managed pool, and how much of it is in use. -<li>Register and unregister root pointers for the garbage collector. -<li>Free the allocator itself. -<li>Consolidate adjacent free blocks to reduce fragmentation. -</ul> - -<p> -For details, see <a href="../base/gsmemory.h">base/gsmemory.h</a>. - -<p> -The allocator API also includes one special hook for the PostScript -interpreter: the concept of stable allocators. See the section on <a -href="#save_forgetsave_restore"><code>save</code> and -<code>restore</code></a> below for details. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsmemraw.h">base/gsmemraw.h</a>, -<a href="../base/gsmemory.c">base/gsmemory.c</a>, -<a href="../base/gsmemory.h">base/gsmemory.h</a>, -<a href="../base/gsstruct.h">base/gsstruct.h</a>, -<a href="../base/gsstype.h">base/gsstype.h</a>. -</dl> - -<h3><a name="Freeing_storage"></a>Freeing storage</h3> - -<p> -Ghostscript's memory management architecture provides three different ways -to free objects: explicitly, by reference counting, or by garbage -collection. They provide different safety / performance / convenience -tradeoffs; we believe that all three are necessary. - -<p> -Objects are always freed as a whole; strings may be freed piecemeal. - -<p> -An object may have an associated finalization procedure, defined in the -structure descriptor. This procedure is called just before the object is -freed, independent of which method is being used to free the object. A few -types of objects have a virtual finalization procedure as well: the -finalization procedure defined in the descriptor simply calls the one in the -object. - -<h4><a name="Explicit_freeing"></a>Explicit freeing</h4> - -<p> -Objects and strings may be freed explicitly, using the -<code>gs_free_</code> virtual procedures in the allocator API. It is up -to the client to ensure that all allocated objects are freed at most once, -and that there are no dangling pointers. - -<p> -Explicit freeing is the fastest method, but is the least convenient and -least safe. It is most appropriate when storage is freed in the same -procedure where it is allocated, or for storage that is known to be -referenced by only one pointer. - -<h4><a name="Reference_counting"></a>Reference counting</h4> - -<p> -Objects may be managed by reference counting. When an object is allocated, -its reference count may be set to 0 or 1. Subsequently, when the reference -count is decremented to 0, the object is freed. - -<p> -The reference counting machinery provides its own virtual finalization -procedure for all reference-counted objects. The machinery calls this -procedure when it is about to free the object (but not when the object is -freed in any other way, which is probably a design bug). This is in -addition to (and called before) any finalization procedure associated with -the object type. - -<p> -Reference counting is as fast as explicit freeing, but takes more space in -the object. It is most appropriate for relatively large objects which are -referenced only from a small set of pointers. Note that reference counting -cannot free objects that are involved in a pointer cycle (e.g., A -> B -> C --> A). - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsrefct.h">base/gsrefct.h</a>. -</dl> - -<h4><a name="Real_garbage_collection"></a>(Real) garbage collection</h4> - -<p> -Objects and strings may be freed automatically by a garbage collector. See -<a href="#Interpreter_GC">below</a>. - -<h3><a name="Special_implementations"></a>Special implementations</h3> - -<h4><a name="malloc"></a>malloc</h4> - -<p> -As mentioned <a href="#Parent_hierarchy">above</a>, the ultimate ancestor of -all allocators with an expandable pool is one that calls -<code>malloc</code>. - -<p>Note that the default gsmalloc.c allocator for malloc/free now uses -a mutex so that allocators that use this can be assured of thread safe -behavior. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsmalloc.h">base/gsmalloc.h</a>, -<a href="../base/gsmalloc.c">base/gsmalloc.c</a>. -</dl> - -<h4><a name="Locking"></a>Locking</h4> - -<p> -In a multi-threaded environment, if an allocator must be callable from -multiple threads (for example, if it is used to allocate structures in one -thread that are passed to, and freed by, another thread), the allocator must -provide mutex protection. Ghostscript provides this capability in the form -of a <em>wrapper</em> allocator, that simply forwards all calls to a -<em>target</em> allocator under protection of a mutex. Using the wrapper -technique, any allocator can be made thread-safe. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsmemlok.h">base/gsmemlok.h</a>, -<a href="../base/gsmemlok.c">base/gsmemlok.c</a>. -</dl> - -<h4><a name="Retrying"></a>Retrying</h4> - -<p> -In an embedded environment, job failure due to memory exhaustion is very -undesirable. Ghostscript provides a wrapper allocator that, when an -allocation attempt fails, calls a client-provided procedure that can attempt -to free memory, then ask for the original allocation to be retried. For -example, such a procedure can wait for a queue to empty, or can free memory -occupied by caches. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsmemret.h">base/gsmemret.h</a>, -<a href="../base/gsmemret.c">base/gsmemret.c</a>. -</dl> - -<h4><a name="Chunk"></a>Chunk</h4> - -<p>When multiple threads are used and there may be frequent memory allocator -requests, mutex contention is a problem and can cause severe performance -degradation. The chunk memory wrapper can provide each thread with its own -instance of an allocator that only makes requests on the underlying (non-GC) -alloctor when large blocks are needed. Small object allocations are managed -within chunks. - -<p>This allocator is intended to be used on top of the basic 'gsmalloc' -allocator (malloc/free) which is NOT garbage collected or relocated and -which MUST be mutex protected. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsmchunk.h">base/gsmchunk.h</a>, -<a href="../base/gsmchunk.c">base/gsmchunk.c</a>. -</dl> - -<h3><a name="Standard_implementation"></a>Standard implementation</h3> - -<p> -The standard Ghostscript allocator gets storage from its parent (normally -the <code>malloc</code> allocator) in large blocks called -<em>clumps</em>, and then allocates objects up from the low end and strings -down from the high end. Large objects or strings are allocated in their own -clump. - -<p> -The standard allocator maintains a set of free-block lists for small object -sizes, one list per size (rounded up to the word size), plus a free-block -list for large objects (but not for objects so large that they get their own -clump: when such an object is freed, its chunk is returned to the parent). -The lists are not sorted; adjacent blocks are only merged if needed. - -<p> -While the standard allocator implements the generic allocator API, and is -usable with the library alone, it includes a special hook for the PostScript -interpreter to aid in the efficient allocation of PostScript composite -objects (arrays and dictionaries). See the section on <a -href="#Refs">Refs</a> below for details. - -<dl> -<dt> -Files: -<dd> -<a href="../base/gsalloc.c">base/gsalloc.c</a>, -<a href="../base/gsalloc.h">base/gsalloc.h</a>, -<a href="../base/gxalloc.h">base/gxalloc.h</a>, -<a href="../base/gxobj.h">base/gxobj.h</a>. -</dl> - -<h3><a name="PostScript_interpreter_extensions"></a>PostScript interpreter extensions</h3> - -<p> -The PostScript interpreter uses an allocator that extends the graphic -library's standard allocator to handle PostScript objects, -<code>save</code> and <code>restore</code>, and real garbage -collection. - -<h4><a name="Refs"></a>Refs (PostScript "objects")</h4> - -<p> -Ghostscript represents what the PLRM calls PostScript "objects" using a -structure called a <code>ref</code>, defined in <a -href="../psi/iref.h">psi/iref.h</a>; packed refs, used for the elements of -packed arrays, are defined in <a href="../psi/ipacked.h">psi/ipacked.h</a>. -See those files for detailed information. - -<dl> -<dt> -Files: -<dd> -<a href="../psi/ipacked.h">psi/ipacked.h</a>, -<a href="../psi/iref.h">psi/iref.h</a>. -</dl> - -<p> -The PLRM calls for two types of "virtual memory" (VM) space: global and -local. Ghostscript adds a third space, <em>system</em> VM, whose lifetime -is an entire session -- i.e., it is effectively "permanent". All three -spaces are subject to garbage collection. There is a separate allocator -instance for each VM space (actually, two instances each for global and -local spaces; see <a href="#save_forgetsave_restore">below</a>). In a -system with multiple contexts and multiple global or local VMs, each global -or local VM has its own allocator instance(s). - -<p> -Refs that represent PostScript composite objects, and therefore include -pointers to stored data, include a 2-bit VM space tag to indicate in which -VM the object data are stored. In addition to system, global, and local VM, -there is a tag for "foreign" VM, which means that the memory is not managed -by a Ghostscript allocator at all. Every store into a composite object must -check for <code>invalidaccess</code>: the VM space tag values are chosen -to help make this check efficient. See <a -href="../psi/ivmspace.h">psi/ivmspace.h</a>, <a -href="../psi/iref.h">psi/iref.h</a>, and <a -href="../psi/store.h">psi/store.h</a> for details. - -<dl> -<dt> -Files: -<dd> -<a href="../psi/ivmspace.h">psi/ivmspace.h</a>. -</dl> - -<p> -PostScript composite objects (arrays and dictionaries) are usually small. -Using a separate memory manager object for each composite object would waste -a lot of space for object headers. Therefore, the interpreter's memory -manager packs multiple composite objects (also called "ref-containing -objects") into a single memory manager object, similar to the way the memory -manager packs multiple objects into a clump (see <a -href="#Standard_implementation">above</a>). See <a -href="../base/gxalloc.h">base/gxalloc.h</a> for details. This memory manager -object has a structure descriptor, like all other memory manager objects. - -<p> -Note that the <code>value.pdict</code>, <code>value.refs</code>, or -<code>value.packed</code> member of a ref must point to a PostScript -composite object, and therefore can point into the middle of a memory -manager object. This requires special handling by the garbage collector (<a -href="#Interpreter_GC">q.v.</a>). - -<dl> -<dt> -Files: -<dd> -<a href="../psi/ialloc.c">psi/ialloc.c</a>, -<a href="../psi/ialloc.h">psi/ialloc.h</a>, -<a href="../psi/iastate.h">psi/iastate.h</a>, -<a href="../psi/iastruct.h">psi/iastruct.h</a>, -<a href="../psi/ilocate.c">psi/ilocate.c</a>, -<a href="../psi/imemory.h">psi/imemory.h</a>, -<a href="../psi/istruct.h">psi/istruct.h</a>. -</dl> - -<h4><a name="save_forgetsave_restore"></a>save/.forgetsave/restore</h4> - -<p> -In addition to <code>save</code> and <code>restore</code>, Ghostscript -provides a <code>.forgetsave</code> operator that makes things as though -a given <code>save</code> had never happened. (In data base terminology, -<code>save</code> is "begin transaction", <code>restore</code> is -"abort transaction", and <code>.forgetsave</code> is "end/commit -transaction"). <code>.forgetsave</code> was implemented for a specific -commercial customer (who may no longer even be using it): it was a pain to -make work, but it's in the code now, and should be maintained. See the -extensive comments in <a href="../psi/isave.c">psi/isave.c</a> for more -information about how these operations work. - -<dl> -<dt> -Files: -<dd> -<a href="../psi/idosave.h">psi/idosave.h</a>, -<a href="../psi/isave.c">psi/isave.c</a>, -<a href="../psi/isave.h">psi/isave.h</a>, -<a href="../psi/isstate.h">psi/isstate.h</a>, -<a href="../psi/store.h">psi/store.h</a>. -</dl> - -<h4><a name="Stable_allocators"></a>Stable allocators</h4> - -<p> -Even though <code>save</code> and <code>restore</code> are concepts -from the PostScript interpreter, the generic allocator architecture and API -include a feature to support them, called <em>stable</em> allocators. Every -allocator has an associated stable allocator, which tags pointers with the -same VM space number but which is not subject to <code>save</code> and -<code>restore</code>. System VM is intrinsically stable (its associated -stable allocator is the same allocator), so there are only 5 allocators in -ordinary single-context usage: system VM, stable global VM, ordinary global -VM, stable local VM, ordinary local VM. - -<p> -The reason that we cannot simply allocate all stable objects in system VM is -that their refs must still be tagged with the correct VM space number, so -that the check against storing pointers from global VM to local VM can be -enforced properly. - -<p> -All PostScript objects are normally allocated with the non-stable -allocators. The stable allocators should be used with care, since using -them can easily create dangling pointers: if storage allocated with a stable -allocator contains any references to PostScript objects, the client is -responsible for ensuring that the references don't outlive the referenced -objects, normally by ensuring that any such referenced objects are allocated -at the outermost <code>save</code> level. - -<p> -The original reason for wanting stable allocators was the PostScript stacks, -which are essentially PostScript arrays but are not subject to -<code>save</code> and <code>restore</code>. Some other uses of stable -allocators are: - -<ul> - -<li>Several per-context structures for DPS. - -<li>Paths (see <code>gstate_path_memory</code> in -<a href="../base/gsstate.c">base/gsstate.c</a>. - -<li>Row buffers for images (see <code>gs_image_row_memory</code> in <a -href="../base/gsimage.c">base/gsimage.c</a>), because the data-reading -procedure for an image can invoke <code>save</code> and -<code>restore</code>. - -<li>Notification lists for fonts, to handle the sequence allocate .. save -.. register .. restore. - -<li>The parameter lists for pdfwrite and epswrite devices (in <a -href="../devices/vector/gdevpsdp.c">devices/vector/gdevpsdp.c</a>), because the whole issue of -local vs. global VM for setpagedevice is, in the words of Ed Taft of Adobe, -"a mess". - -<li>Many places in the pdfwrite driver, because many of its bookkeeping -structures must not be restorable. - -</ul> - -<p> -For more specific examples, search the sources for references to -<code>gs_memory_stable</code>. - -<h4><a name="Interpreter_GC"></a>Garbage collection</h4> - -<p> -The interpreter's garbage collector is a compacting, non-conservative, -mark-and-sweep collector. - -<ul> -<li>It compacts storage because that is the only way to avoid permanent -sandbars, which is essential in limited-memory environments. -<li>It is non-conservative because conservative collectors (which attempt -to determine whether arbitrary bit patterns are pointers) cannot compact. -<li>It uses mark-and-sweep, rather than a more modern copying approach, -because it cannot afford the extra memory required for copying. -</ul> - -<p> -Because the garbage collector is non-conservative, it cannot be run if there -are any pointers to movable storage from the C stack. Thus it cannot be run -automatically when the allocator is unable to allocate requested space. -Instead, when the allocator has allocated a given amount of storage (the -<code>vm_threshold</code> amount, corresponding to the PostScript -<code>VMThreshold</code> parameter), it sets a flag that the interpreter -checks in the main loop. When the interpreter sees that this flag is set, -it calls the garbage collector: at that point, there are no problematic -pointers from the stack. - -<p> -Roots for tracing must be registered with the allocator. Most roots are -registered during initialization. - -<p> -"Mark-and-sweep" is a bit of a misnomer. The garbage collector actually has -5 main phases: - -<ul> -<li>Sweep to clear marks; -<li>Trace and mark; -<li>Sweep to compute relocation; -<li>Sweep to relocate pointers; -<li>Sweep and compact. -</ul> - -<p> -There is some extra complexity to handle collecting local VM only. In this -case, all pointers in global VM are treated as roots, and global VM is not -compacted. - -<p> -As noted above, PostScript arrays and strings can have refs that point -within them (because of <code>getinterval</code>). Thus the garbage -collector must mark each element of an array, and even each byte of a -string, individually. Specifically, it marks objects, refs, and strings -using 3 different mechanisms: - -<ul> - -<li>Objects have a mark bit in their header: see -<a href="../base/gxobj.h">base/gxobj.h</a>, - -<li>Refs and packed refs have a reserved mark bit: see <a -href="../psi/iref.h">psi/iref.h</a> and <a -href="../psi/ipacked.h">psi/ipacked.h</a>. - -<li>Strings use a separate bit table, with one bit per string byte: see -<a href="../base/gxalloc.h">base/gxalloc.h</a>, - -</ul> - -<p> -Similarly, it records the relocation information for objects, refs, and -strings differently: - -<ul> - -<li>Objects record relocation in the object header. - -<li>Refs record relocation in unused fields of refs such as nulls that -don't use their <code>value</code> field. Every memory manager object -that stores ref-containing objects as described above has an extra, unused -ref at the end for this purpose. - -<li>Strings use a separate relocation table. - -</ul> - -<dl> -<dt> -Files: -<dd> -<a href="../psi/igc.c">psi/igc.c</a>, -<a href="../psi/igc.h">psi/igc.h</a>, -<a href="../psi/igcref.c">psi/igcref.c</a>, -<a href="../psi/igcstr.c">psi/igcstr.c</a>, -<a href="../psi/igcstr.h">psi/igcstr.h</a>, -<a href="../psi/ireclaim.c">psi/ireclaim.c</a>. -</dl> - -<hr> - -<h2><a name="Portability"></a>Portability</h2> - -<p> -One of Ghostscript's most important features is its great portability across -platforms (CPUs, operating systems, compilers, and build tools). The code -supports portability through two mechanisms: - -<ul> - -<li><a href="#Structural">Structural mechanisms</a> -- segregating -platform-dependent information into files in a particular way. - -<li><a href="#Coding">Coding standards</a> -- avoiding relying on byte -order, scalar size, and platform-specific compiler or library features. - -</ul> - -<h3><a name="Structural"></a>Structural</h3> - -<h4><a name="CPU_and_compiler"></a>CPU and compiler</h4> - -<p> -Ghostscript attempts to discover characteristics of the CPU and compiler -automatically during the build process, by compiling and then executing a -program called <code>genarch</code>. <code>genarch</code> generates a -file <code>obj/arch.h</code>, which almost all Ghostscript files then -include. This works well for things like word size, byte order, and -floating point representation, but it can't determine whether or not a -compiler supports a particular feature, because if a feature is absent, the -compilation may fail. - -<dl> -<dt> -Files: -<dd> -<a href="../base/genarch.c">base/genarch.c</a>, -<a href="../obj/arch.h">obj/arch.h</a>. -</dl> - -<h4><a name="Library_headers"></a>Library headers</h4> - -<p> -Despite the supposed standardization of ANSI C, platforms vary considerably -in where (and whether) they provide various standard library facilities. -Currently, Ghostscript's build process doesn't attempt to sort this out -automatically. Instead, for each library header file -<code><</code><em>xxx</em><code>.h></code> there is a -corresponding Ghostscript source file -<code>base/</code><em>xxx</em><code>_.h</code>, containing a set of -compile-time conditionals that attempt to select the correct platform header -file, or in some cases substitute Ghostscript's own code for a missing -facility. You may need to edit these files when moving to platforms with -unusually non-standard libraries. - -<dl> -<dt> -Files: -<dd> -<a href="../base/ctype_.h">base/ctype_.h</a>, -<a href="../base/dirent_.h">base/dirent_.h</a>, -<a href="../base/dos_.h">base/dos_.h</a>, -<a href="../base/errno_.h">base/errno_.h</a>, -<a href="../base/fcntl_.h">base/fcntl_.h</a>, -<a href="../base/jerror_.h">base/jerror_.h</a>, -<a href="../base/malloc_.h">base/malloc_.h</a>, -<a href="../base/math_.h">base/math_.h</a>, -<a href="../base/memory_.h">base/memory_.h</a>, -<a href="../base/pipe_.h">base/pipe_.h</a>, -<a href="../base/png_.h">base/png_.h</a>, -<a href="../base/setjmp_.h">base/setjmp_.h</a>, -<a href="../base/stat_.h">base/stat_.h</a>, -<a href="../base/stdint_.h">base/stdint_.h</a>, -<a href="../base/stdio_.h">base/stdio_.h</a>, -<a href="../base/string_.h">base/string_.h</a>, -<a href="../base/time_.h">base/time_.h</a>, -<a href="../base/unistd_.h">base/unistd_.h</a>, -<a href="../base/vmsmath.h">base/vmsmath.h</a>, -<a href="../base/windows_.h">base/windows_.h</a>, -<a href="../base/x_.h">base/x_.h</a>. -</dl> - -<p> -It has been suggested that the GNU <code>configure</code> scripts do the -above better, for Unix systems, than Ghostscript's current methods. While -this may be true, we have found <code>configure</code> scripts difficult -to write, understand, and maintain; and the <code>autoconf</code> tool -for generating <code>configure</code> scripts, which we found easy to -use, doesn't cover much of the ground that Ghostscript requires. - -<h4><a name="Cross_platform_APIs"></a>Cross-platform APIs</h4> - -<p> -For a few library facilities that are available on all platforms but are not -well standardized, or that may need to be changed for special environments, -Ghostscript defines its own APIs. It is an architectural property of -Ghostscript that the implementations of these APIs are the only .c files for -which the choice of platform (as opposed to choices of drivers or optional -features) determines whether they are compiled and linked into an -executable. - -<dl> - -<dt> -API: -<dd> -<a href="../base/gp.h">base/gp.h</a>, -<a href="../base/gpcheck.h">base/gpcheck.h</a>, -<a href="../base/gpgetenv.h">base/gpgetenv.h</a>, -<a href="../base/gpmisc.h">base/gpmisc.h</a>, -<a href="../base/gpsync.h">base/gpsync.h</a>. - -<dt> -Implementation files shared among multiple platforms: -<dd> -<a href="../base/gp_getnv.c">base/gp_getnv.c</a>, -<a href="../base/gp_mktmp.c">base/gp_mktmp.c</a>, -<a href="../base/gp_nsync.c">base/gp_nsync.c</a>, -<a href="../base/gp_paper.c">base/gp_paper.c</a>, -<a href="../base/gp_psync.c">base/gp_psync.c</a>, -<a href="../base/gp_strdl.c">base/gp_strdl.c</a>, -<a href="../base/gpmisc.c">base/gpmisc.c</a>. - -<dt> -Platform-specific implementation files: -<dd> -<a href="../base/gp_dosfe.c">base/gp_dosfe.c</a>, -<a href="../base/gp_dosfs.c">base/gp_dosfs.c</a>, -<a href="../base/gp_dvx.c">base/gp_dvx.c</a>, -<a href="../base/gp_msdos.c">base/gp_msdos.c</a>, -<a href="../base/gp_mshdl.c">base/gp_mshdl.c</a>, -<a href="../base/gp_mslib.c">base/gp_mslib.c</a>, -<a href="../base/gp_mswin.c">base/gp_mswin.c</a>, -<a href="../base/gp_mswin.h">base/gp_mswin.h</a>, -<a href="../base/gp_ntfs.c">base/gp_ntfs.c</a>, -<a href="../base/gp_os2.c">base/gp_os2.c</a>, -<a href="../base/gp_os2.h">base/gp_os2.h</a>, -<a href="../base/gp_os2fs.c">base/gp_os2fs.c</a>, -<a href="../base/gp_os9.c">base/gp_os9.c</a>, -<a href="../base/gp_stdia.c">base/gp_stdia.c</a>, -<a href="../base/gp_stdin.c">base/gp_stdin.c</a>, -<a href="../base/gp_unifn.c">base/gp_unifn.c</a>, -<a href="../base/gp_unifs.c">base/gp_unifs.c</a>, -<a href="../base/gp_unix.c">base/gp_unix.c</a>, -<a href="../base/gp_unix_cache.c">base/gp_unix_cache.c</a>, -<a href="../base/gp_upapr.c">base/gp_upapr.c</a>, -<a href="../base/gp_vms.c">base/gp_vms.c</a>, -<a href="../base/gp_wgetv.c">base/gp_wgetv.c</a>, -<a href="../base/gp_win32.c">base/gp_win32.c</a>, -<a href="../base/gp_wpapr.c">base/gp_wpapr.c</a>, -<a href="../base/gp_wsync.c">base/gp_wsync.c</a>, -<a href="../base/gs_dll_call.h">base/gs_dll_call.h</a>. - -</dl> - -<h4><a name="Makefiles"></a>Makefiles</h4> - -<p> -For information on the structure and conventions used within makefiles, see -the <a href="#Makefile_structure">Makefile structure</a> section above. - -<p> -Ghostscript's makefiles are structured very similarly to the cross-platform -library files. The great majority of the makefiles are portable across all -platforms and all versions of <code>make</code>. To achieve this, the -platform-independent makefiles must obey two constraints beyond those of the -POSIX <code>make</code> program: - -<ul> - -<li>No conditionals or <code>include</code>s are allowed. While most -<code>make</code> programs now provide some form of conditional execution -and some form of inclusion, there is no agreement on the syntax. -(Conditionals and includes are allowed in platform-dependent makefiles; in -fact, an inclusion facility is required.) - -<li>There must be a space on both sides of the : that separates the target -of a rule from its dependencies. This is required for compatibility with -the OpenVMS <code>MMS</code> and <code>MMK</code> programs. - -</ul> - -<p> -The top-level makefile for each platform (where "platform" includes the OS, -the compiler, and the flavor of <code>make</code>) contains all the build -options, plus <code>include</code>s for the generic makefiles and any -platform-dependent makefiles that are shared among multiple platforms. - -<p> -While most of the top-level makefiles build a PostScript and/or PDF -interpreter configuration, there are also a few makefiles that build a test -program that only uses the graphics library without any language -interpreter. Among other things, this can be helpful in verifying that no -accidental dependencies on the interpreter have crept into the library or -drivers. - -<p> -For families of similar platforms, the question arises whether to use -multiple top-level makefiles, or whether to use a single top-level makefile -that may require minor editing for some (or all) platforms. Ghostscript -currently uses the following top-level makefiles for building interpreter -configurations: - -<ul> - -<li>POSIX systems (inluding Linux and Unix): -<ul> -<li><a href="../configure.ac"configure.ac</a>, -GNU Autoconf source script for automatic build configuration. -<li><a href="../Makefile.in">Makefile.in</a>, -source for the top-level makefile used in the Autoconf build. -<li><a href="../base/unix-gcc.mak">base/unix-gcc.mak</a>, -for Unix with gcc. -<li><a href="../base/unixansi.mak">base/unixansi.mak</a>, -for Unix with an ANSI C compiler other than gcc. -</ul> - -<li>PC: -<ul> -<li><a href="../ghostscript.vcproj">ghostscript.vcproj</a>, -Visual Studio project file used to build Ghostscript. -<li><a href="../psi/msvc32.mak">psi/msvc32.mak</a>, -for MS Windows with Microsoft Visual C (MSVC). -<li><a href="../psi/os2.mak">psi/os2.mak</a>, -for MS-DOS or OS/2 GCC/EMX environment. -</ul> - -<li>Macintosh: -<ul> -<li><a href="../base/macosx.mak">base/macosx.mak</a>, -commandline makefile for MacOS X. -<li><a href="../base/macos-mcp.mak">base/macos-mcp.mak</a>, -dummy makefile to generate an xml project file for Metrowerks Codewarrior. -</ul> - - -<li>Other: -<ul> -<li><a href="../base/all-arch.mak">base/all-arch.mak</a>, -for building on many Unix systems in a networked test environment. -<li><a href="../base/openvms.mak">base/openvms.mak</a>, -for OpenVMS with Digital's CC compiler and the MMS build program. -<li><a href="../base/openvms.mmk">base/openvms.mmk</a>, -for OpenVMS with Digital's CC compiler and the MMK build program. -</ul> - -</ul> - -<p> -The following top-level makefiles build the library test program: - -<ul> -<li><a href="../base/ugcclib.mak">base/ugcclib.mak</a>, -on Unix with gcc. -<li><a href="../base/msvclib.mak">base/msvclib.mak</a>, -on MS Windows with MSVC. -</ul> - -<p> -The MSVC makefiles may require editing to select between different versions -of MSVC, since different versions may have slightly incompatible command -line switches or customary installation path names. The Unix makefiles -often require editing to deal with differing library path names and/or -library names. For details, see <a href="Make.htm#Unix_build">the Unix -section</a> of the documentation for building Ghostscript. - -<dl> - -<dt> -Library test program: -<dd> -<a href="../base/gslib.c">base/gslib.c</a>. - -<dt> -Platform-independent makefiles: -<dd> - -<dl> - -<dt> -Graphics library and support: -<dd> -<a href="../devices/contrib.mak">devices/contrib.mak</a>, -<a href="../devices/devs.mak">devices/devs.mak</a>, -<a href="../base/gs.mak">base/gs.mak</a>, -<a href="../base/lib.mak">base/lib.mak</a>, -<a href="../base/version.mak">base/version.mak</a>. - -<dt> -PostScript interpreter and fonts: -<dd> -<a href="../psi/int.mak">psi/int.mak</a>. - -<dt> -Third-party libraries: -<dd> -<a href="../base/expat.mak">base/expat.mak</a>, -<a href="../base/ijs.mak">base/ijs.mak</a>, -<a href="../base/jbig2.mak">base/jbig2.mak</a>, -<a href="../base/ldf_jb2.mak">base/ldf_jb2.mak</a>, -<a href="../base/lwf_jp2.mak">base/lwf_jp2.mak</a>, -<a href="../base/jpeg.mak">base/jpeg.mak</a>, -<a href="../base/png.mak">base/png.mak</a>, -<a href="../base/zlib.mak">base/zlib.mak</a>. -</dl> - -<dt> -Shared platform-dependent makefiles: -<dd> - -<dl> - -<dt> -Unix: -<dd> -<a href="../base/unix-aux.mak">base/unix-aux.mak</a>, -<a href="../base/unix-dll.mak">base/unix-dll.mak</a>, -<a href="../base/unix-end.mak">base/unix-end.mak</a>, -<a href="../base/unixhead.mak">base/unixhead.mak</a>, -<a href="../base/unixinst.mak">base/unixinst.mak</a>, -<a href="../base/unixlink.mak">base/unixlink.mak</a>. - -<dt> -Microsoft Windows and MS-DOS: -<dd> -<a href="../base/msvccmd.mak">base/msvccmd.mak</a>, -<a href="../base/msvctail.mak">base/msvctail.mak</a>, -<a href="../base/pcwin.mak">base/pcwin.mak</a>, -<a href="../psi/winint.mak">psi/winint.mak</a>, -<a href="../base/winlib.mak">base/winlib.mak</a>, -<a href="../base/winplat.mak">base/winplat.mak</a>. - -</dl> - -</dl> - -<h3><a name="Coding"></a>Coding</h3> - -<p> -Coding for portability requires avoiding both <em>explicit</em> -dependencies, such as platform-dependent <code>#ifdef</code>s, and -<em>implicit</em> dependencies, such as dependencies on byte order or the -size of the integral types. - -<h4><a name="Explicit_dependencies"></a>Explicit dependencies</h4> - -<p> -The platform-independent .c files never, ever, use <code>#ifdef</code> or -<code>#if</code> to select code for specific platforms. Instead, we -always try to characterize some abstract property that is being tested. For -example, rather than checking for macros that are defined on those specific -platforms that have 64-bit <code>long</code> values, we define a macro -<code>ARCH_SIZEOF_LONG</code> that can then be tested. Such macros are -always defined in a .h file, either automatically in <code>arch.h</code>, -or explicitly in a <em>xxx</em><code>_.h</code> file, as described in -earlier sections. - -<dl> -<dt> -Files: -<dd> -<a href="../base/std.h">base/std.h</a>, -<a href="../base/stdpn.h">base/stdpn.h</a>, -<a href="../base/stdpre.h">base/stdpre.h</a>. -</dl> - -<h4><a name="Implicit_dependencies"></a>Implicit dependencies</h4> - -<p> -The most common source of byte ordering dependencies is casting between -types (T1 *) and (T2 *) where T1 and T2 are numeric types that aren't merely -signed/unsigned variants of each other. To avoid this, the only casts -allowed in the code are between numeric types, from a pointer type to a long -integral type, and between pointer types. - -<p> -Ghostscript's code assumes the following about the sizes of various types: - -<dl> -<dt>char<dd>8 bits -<dt>short<dd>16 bits -<dt>int<dd>32 or 64 bits -<dt>long<dd>32 or 64 bits -<dt>float<dd>32 bits (may work with 64 bits) -<dt>double<dd>64 bits (may work with 128 bits) -</dl> - -<p> -The code does not assume that the <code>char</code> type is signed (or -unsigned); except for places where the value is always a literal string, or -for interfacing to library procedures, the code uses <code>byte</code> (a -Ghostscript synonym for <code>unsigned char</code>) almost everywhere. - -<p> -Pointers are signed on some platforms and unsigned on others. In the few -places in the memory manager where it's necessary to reliably order-compare -(as opposed to equality-compare) pointers that aren't known to point to the -same allocated block of memory, the code uses the -<code>PTR_</code><em>relation</em> macros rather than direct comparisons. - -<p> -See the files listed above for other situations where a macro provides -platform-independence or a workaround for bugs in specific compilers or -libraries (of which there are a distressing number). - -<h4><a name="Platform_specific_code"></a>Platform-specific code</h4> - -<p> -There are some features that are inherently platform-specific: - -<ul> - -<li>Microsoft Windows requires a lot of special top-level code, and also has -an installer and uninstaller. - -<li>OS/2 requires a little special code. - -<li>MacOS also requires special top-level code (now distributed with the -standard Ghostscript package). - -<li>All platforms supporting DLLs (currently all three of the above) share -some special top-level code. - -</ul> - -<dl> - -<dt> -MS Windows files: -<dd> -<a href="../psi/dpmain.c">psi/dpmain.c</a>, -<a href="../psi/dwdll.c">psi/dwdll.c</a>, -<a href="../psi/dwdll.h">psi/dwdll.h</a>, -<a href="../psi/dwimg.c">psi/dwimg.c</a>, -<a href="../psi/dwimg.h">psi/dwimg.h</a>, -<a href="../psi/dwmain.c">psi/dwmain.c</a>, -<a href="../psi/dwmainc.c">psi/dwmainc.c</a>, -<a href="../psi/dwnodll.c">psi/dwnodll.c</a>, -<a href="../psi/dwreg.c">psi/dwreg.c</a>, -<a href="../psi/dwreg.h">psi/dwreg.h</a>, -<a href="../psi/dwres.h">psi/dwres.h</a>, -<a href="../psi/dwtext.c">psi/dwtext.c</a>, -<a href="../psi/dwtext.h">psi/dwtext.h</a>, -<a href="../psi/dwtrace.c">psi/dwtrace.c</a>, -<a href="../psi/dwtrace.h">psi/dwtrace.h</a>, -<a href="../base/gp_msdll.c">base/gp_msdll.c</a>, -<a href="../base/gp_mspol.c">base/gp_mspol.c</a>, -<a href="../base/gp_msprn.c">base/gp_msprn.c</a>, -<a href="../base/gsdllwin.h">base/gsdllwin.h</a>. - -<dt> -OS/2 files: -<dd> -<a href="../base/gp_os2pr.c">base/gp_os2pr.c</a>, - -<dt> -Unix files: -<dd> -<a href="../psi/dxmain.c">psi/dxmain.c</a>, -<a href="../psi/dxmainc.c">psi/dxmainc.c</a>. - -<dt> -Macintosh files: -<dd> -<a href="../devices/gdevmac.c">devices/gdevmac.c</a>, -<a href="../devices/gdevmac.h">devices/gdevmac.h</a>, -<a href="../devices/gdevmacpictop.h">devices/gdevmacpictop.h</a>, -<a href="../devices/gdevmacttf.h">devices/gdevmacttf.h</a>, -<a href="../base/gp_mac.c">base/gp_mac.c</a>, -<a href="../base/gp_mac.h">base/gp_mac.h</a>, -<a href="../base/gp_macio.c">base/gp_macio.c</a>, -<a href="../base/gp_macpoll.c">base/gp_macpoll.c</a>, -<a href="../base/gsiomacres.c">base/gsiomacres.c</a>, -<a href="../base/macgenmcpxml.sh">base/macgenmcpxml.sh</a>, -<a href="../base/macsystypes.h">base/macsystypes.h</a>, -<a href="../base/macos_carbon_pre.h">base/macos_carbon_pre.h</a>, -<a href="../base/macos_carbon_d_pre.h">base/macos_carbon_d_pre.h</a>, -<a href="../base/macos_classic_d_pre.h">base/macos_classic_d_pre.h</a>, - -<a href="../psi/dmmain.c">psi/dmmain.c</a>, -<a href="../psi/dmmain.r">psi/dmmain.r</a>. - -<dt> -VMS files: -<dd> -<a href="../base/vms_x_fix.h">base/vms_x_fix.h</a>. - -<dt> -DLL files: -<dd> -<a href="../psi/gsdll.c">psi/gsdll.c</a>, -<a href="../base/gsdll.h">base/gsdll.h</a>, -<a href="../devices/gdevdsp.c">devices/gdevdsp.c</a>, -<a href="../devices/gdevdsp.h">devices/gdevdsp.h</a>, -<a href="../devices/gdevdsp2.h">devices/gdevdsp2.h</a>, -<a href="../psi/iapi.c">psi/iapi.c</a>, -<a href="../psi/iapi.h">psi/iapi.h</a>, -<a href="../psi/idisp.c">psi/idisp.c</a>, -<a href="../psi/idisp.h">psi/idisp.h</a>. -<p> -The new DLL interface (new as of 7.0) is especially useful with the -new display device, so it is included here. Both are due to Russell -Lang. - -</dl> - - -<hr> - -<h2><a name="Troubleshooting"></a>Troubleshooting</h2> - -<p> -The Ghostscript code has many tracing and debugging features that can be -enabled at run time using the <code>-Z</code> command line switch, if the -executable was compiled with <code>DEBUG</code> defined. One -particularly useful combination is <code>-Z@\?</code>, which fills free -memory blocks with a pattern and also turns on run-time memory consistency -checking. For more information, see <a -href="Use.htm#Debugging">doc/Use.htm#Debugging</a>; you can also search for -occurrences of <code>if_debug</code> or <code>gs_debug_c</code> in the -source code. Note that many of these features are in the graphics library -and do not require a PostScript interpreter. - -<p> -The code also contains many run-time procedures whose only purpose is to be -called from the debugger to print out various data structures, including all -the procedures in <a href="../psi/idebug.c">psi/idebug.c</a> (for the -PostScript interpreter) and the <code>debug_dump_</code> procedures in <a -href="../base/gsmisc.c">base/gsmisc.c</a>. - -<dl> -<dt> -Files: -<dd> -<a href="Use.htm#Debugging">doc/Use.htm#Debugging</a>, -<a href="../base/gdebug.h">base/gdebug.h</a>, -<a href="../base/gsmdebug.h">base/gsmdebug.h</a>, -<a href="../psi/idebug.h">psi/idebug.h</a>, -<a href="../psi/idebug.c">psi/idebug.c</a>. -</dl> - -<hr> - -<h2><a name="Profiling"></a>Profiling</h2> -<h3><a name="ProfilingMSVC6"></a>Profiling with Microsoft Developer Studio 6</h3> - -<p> -The Microsoft profiling tool is included into Microsoft Developer Studio 6 -Enterprise Edition only. Standard Edition and Professional Edition do not include it. - -<p> -Microsoft profiler tool requires the application to be linked with -a special linker option. To provide it you need the following change to -<code>gs/base/msvccmd.mak</code> : - -<blockquote><pre><code> - -*** SVN-GS\HEAD\gs\src\msvccmd.mak Tue Jan 9 21:41:07 2007 ---- gs\src\msvccmd.mak Mon May 7 11:29:35 2007 -*************** -*** 159,163 **** - # Note that it must be followed by a space. - CT=/Od /Fd$(GLOBJDIR) $(NULL) $(CDCC) $(CPCH) -! LCT=/DEBUG /INCREMENTAL:YES - COMPILE_FULL_OPTIMIZED= # no optimization when debugging - COMPILE_WITH_FRAMES= # no optimization when debugging ---- 159,164 ---- - # Note that it must be followed by a space. - CT=/Od /Fd$(GLOBJDIR) $(NULL) $(CDCC) $(CPCH) -! # LCT=/DEBUG /INCREMENTAL:YES -! LCT=/DEBUG /PROFILE - COMPILE_FULL_OPTIMIZED= # no optimization when debugging - COMPILE_WITH_FRAMES= # no optimization when debugging -*************** -*** 167,175 **** - !if $(DEBUGSYM)==0 - CT= -! LCT= - CMT=/MT - !else - CT=/Zi /Fd$(GLOBJDIR) $(NULL) -! LCT=/DEBUG - CMT=/MTd - !endif ---- 168,178 ---- - !if $(DEBUGSYM)==0 - CT= -! # LCT= -! LCT=/PROFILE - CMT=/MT - !else - CT=/Zi /Fd$(GLOBJDIR) $(NULL) -! # LCT=/DEBUG -! LCT=/DEBUG /PROFILE - CMT=/MTd - !endif - -</code></pre></blockquote> - -Note that any of debug and release build may be profiled. - -<p> -Mictosoft Profiler tool can't profile a dynamically loaded DLLs. -When building Ghostscript with makefiles you need to specify -<code>MAKEDLL=0</code> to <code>nmake</code> command line. - -<p> -The Integrated Development Environment of Microsoft Developer Studio 6 -cannot profile a makefile-based project. Therefore the profiling tool -to be started from command line. - -<p> -The profiling from command line is a 4 step procedure. -The following batch file provides a sample for it : - -<blockquote><pre><code> - -set DEVSTUDIO=G:\Program Files\Microsoft Visual Studio -set GS_HOME=..\..\gs-hdp -set GS_COMMAND_LINE=%GS_HOME%\bin\gswin32c.exe -I%GS_HOME%\lib;f:\afpl\fonts -r144 -dBATCH -dNOPAUSE -d/DEBUG attachment.pdf -set START_FUNCTION=_main -set Path=%DEVSTUDIO%\Common\MSDev98\Bin;%DEVSTUDIO%\VC98\Bin -PREP.EXE /OM /SF %START_FUNCTION% /FT %GS_HOME%\bin\gswin32c.exe -If ERRORLEVEL 1 echo step 1 fails&exit -PROFILE /I %GS_HOME%\bin\gswin32c.pbi %GS_COMMAND_LINE% -If ERRORLEVEL 1 echo step 2 fails&exit -PREP /M %GS_HOME%\bin\gswin32c /OT xxx.pbt -If ERRORLEVEL 1 echo step 3 fails&exit -PLIST /ST xxx.pbt >profile.txt -If ERRORLEVEL 1 echo step 4 fails&exit - -</code></pre></blockquote> - -<p> -This batch file to be adopted to your configuration : - -<ul> -<li> -Edit the path to developer studio in the line 1. -<li> -Edit the Ghostscript home directory in the line 2. -<li> -Edit Ghostscript command line in line 3. Note that profiling without /NOPAUSE is a bad idea. -<li> -In the line 4 edit the function name to start the profiling from. -The sample code specifies _main as the starting function. -Note it is the linker's function name, which starts with underscore. -<li> -Edit the output file name in the line 5. -</ul> - - - - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2001-2022 Artifex Software, Inc. All rights -reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Devices.htm b/doc/Devices.htm deleted file mode 100644 index 4787ebd7..00000000 --- a/doc/Devices.htm +++ /dev/null @@ -1,2175 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Details of Ghostscript Output Devices</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Details of Ghostscript Output Devices</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Measurements">Notes on measurements</a></li> - <li><a href="#File_formats">Image file formats</a></li> - <li> - <ul> - <li><a href="#PNG">PNG file format</a></li> - <li><a href="#JFIF">JPEG file format (JFIF)</a></li> - <li><a href="#PNM">PNM file format</a></li> - <li><a href="#TIFF">TIFF file formats</a></li> - <li><a href="#fax">fax file formats</a></li> - <li><a href="#BMP">BMP file format</a></li> - <li><a href="#PCX">PCX file format</a></li> - <li><a href="#PSD">PSD file format (DeviceN color model)</a></li> - <li><a href="#PDFimage">Bitmap PDF output, PCLm output</a></li> - </ul> - </li> - <li><a href="#OCR-Devices">OCR Devices</a></li> - <li> - <ul> - <li><a href="#OCR">OCR text output</a></li> - <li><a href="#PDFocr">Bitmap PDF output (with OCR text)</a></li> - <li><a href="#PDFwriteocr">Vector PDF output (with OCR Unicode CMaps)</a></li> - </ul> - </li> - <li><a href="#High-level">High level formats</a></li> - <li> - <ul> - <li><a href="#PDF">PDF file output</a></li> - <li><a href="#OCR">OCR devices</a></li> - <li><a href="#PS">PostScript file output</a></li> - <li><a href="#EPS">EPS file output</a></li> - <li><a href="#PXL">PCL-XL file output</a></li> - <li><a href="#TXT">Text output</a></li> - </ul> - </li> - <li><a href="#Display_devices">Display devices</a></li> - <li> - <ul> - <li><a href="#x11_devices">X Window System</a></li> - <li><a href="#display_device">display device (MS Windows, OS/2, gtk+)</a></li> - </ul> - </li> - <li><a href="#IJS">IJS - Inkjet and other raster devices</a></li> - <li><a href="#Rinkj">Rinkj - Resplendent inkjet driver</a></li> - <li><a href="#HP_ijs">HP Deskjet official drivers</a></li> - <li><a href="#gimp-print">Gimp-Print driver collection</a></li> - <li><a href="#Win">MS Windows printers</a></li> - <li><a href="#SPARCprinter">Sun SPARCprinter</a></li> - <li> - <ul> - <li><a href="#SPARC_install">Installation</a></li> - <li><a href="#SPARC_problems">Problems</a></li> - </ul> - </li> - <li><a href="#Apple">Apple dot matrix printer</a></li> - <li><a href="#Test">Special and Test devices</a></li> - <li> - <ul> - <li><a href="#Bit">Raw 'bit' output.</a></li> - <li><a href="#Bounding_box_output">Bounding Box output.</a></li> - <li><a href="#Ink_coverage_output">Ink coverage output.</a></li> - <li><a href="#Permute">Permutation (DeviceN color model)</a></li> - <li><a href="#SPOT">spotcmyk (DeviceN color model)</a></li> - <li><a href="#XCF">XCF (DeviceN color model)</a></li> - <li><a href="#bitraw">Raw 'bit' devices</a></li> - </ul> - </li> -</ul> - - - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. You may also be interested in <a href="Make.htm">how to -build Ghostscript</a> and <a href="Install.htm">install it</a>, as well as -the description of the <a href="Drivers.htm">driver interface</a>.</p> - -<p>Documentation for some older, superceded devices has been moved to -<a href="Deprecated.htm">another document</a>. In general such devices are deprecated -and will be removed in future versions of Ghostscript. In general all older printer -drivers can be replaced by the ijs interface and one of the available 3rd party raster -driver collections. We recommend moving to the ijs device for all such printing.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Measurements"></a>Notes on measurements</h2> - -<p> -Several different important kinds of measures appear throughout this -document: inches, centimeters and millimeters, points, and bits per pixel.</p> - -<dl> - -<dt>Centimeters and millimeters</dt> -<dd>ISO standard paper sizes such as A4 and A3 are commonly represented in -the SI units of centimeters and millimeters. Centimeters are abbreviated -<dfn><abbr>cm</abbr></dfn>, millimeters <dfn><abbr>mm</abbr></dfn>. ISO A4 paper is -quite close to 210×297 millimeters (approximately 8.3×11.7 -inches).</dd> - -<dt>Inches</dt> -<dd>1 inch equals 2.54 centimeters. The inch measure is sometimes -represented by <dfn><abbr>in</abbr></dfn> or a quotation mark -(<abbr>"</abbr>) to the right -of a measure, like 8.5in or 8.5". -U.S. "letter" paper is exactly -8.5in×11in, approximately 21.6cm×27.9cm. (See in the usage -documentation all the <a href="Use.htm#Known_paper_sizes">paper sizes -predefined in Ghostscript</a>.)</dd> - -<dt>Points</dt> -<dd>Points are a measure traditionally used in the printing trade and now -in PostScript, which specifies exactly 72 points per inch (approximately -28.35 per centimeter). The <a href="Use.htm#Known_paper_sizes">paper sizes -known to Ghostscript</a> are defined in the initialization file -<code>gs_statd.ps</code> in terms of points.</dd> - -<dt>Dots per inch</dt> -<dd>Dots per inch or <dfn><abbr>dpi</abbr></dfn> is the common measure of -printing resolution in the US.</dd> - -<dt>Bits per pixel</dt> -<dd>Commonly abbreviated <dfn><abbr>bpp</abbr></dfn> this is the number of -digital bits used to represent the color of each pixel. This is also referred -to as 'bit depth' or 'pixel depth'.</dd> - -</dl> - -<hr> - -<h2><a name="File_formats"></a>Image file formats</h2> - -<p> -Ghostscript supports output to a variety of image file formats -and is widely used for rasterizing postscript and pdf files. -A collection of such formats ('output devices' in Ghostscript terminology) -are described in this section. -</p> - -<p> -Here are some commonly useful driver options that apply to all raster drivers. -Options specific to particular file formats are described in their respective -sections below.</p> - -<blockquote><dl> - -<dt>-sOutputFile=<em>filename</em></dt> -<dd><p>This is a general option telling Ghostscript what to name the output. -It can either be a single filename '<code>tiger.png</code>' or a template - '<code>figure-%03d.jpg</code>' where the <code>%03d</code> is replaced by the page number.</p></dd> - - -<dt>-r<em>res</em></dt> -<dt>-r<em>xres</em>x<em>yres</em></dt> -<dd><p>This option sets the resolution of the output file in dots per inch. -The default value if you don't specify this options is usually 72 <abbr>dpi</abbr>.</p></dd> - -<dt>-dTextAlphaBits=<em>n</em></dt> -<dt>-dGraphicsAlphaBits=<em>n</em></dt> -<dd><p>These options control the use of subsample antialiasing. Their use is highly recommended -for producing high quality rasterizations of the input files. The size of the subsampling -box <em>n</em> should be 4 for optimum output, but smaller values can be used for faster -rendering. Antialiasing is enabled separately for text and graphics content.</p> -<p>Because this feature relies upon rendering the input it is incompatible, and will generate -an error on attempted use, with any of the vector output devices.</p> -</dd> -</dl> -</blockquote> - -<p> -It is also conventional to call Ghostscript with the '<code>-dSAFER -dBATCH -dNOPAUSE</code>' trio -of options when rasterizing to a file. These suppress interactive prompts and enable some -security checks on the file to be run. Please see the <a href="Use.htm">Use documentation</a> -for a complete description. -</p> - -<h3><a name="PNG"></a>PNG file format</h3> - -<p><acronym>PNG</acronym> (pronounced 'ping') stands for Portable Network Graphics, -and is the recommended format for high-quality images. It supports full quality -color and transparency, offers excellent lossless compression of the image data, -and is widely supported. Please see the -<a href="http://www.libpng.org/pub/png/pngintro.html" class="offsite">PNG website</a> -for a complete description of the format.</p> - -<p>Ghostscript provides a variety of devices for <acronym>PNG</acronym> output -varying by bit depth. For normal use we recommend <code>png16m</code> for 24-bit RGB color, -or <code>pnggray</code> for grayscale. The <code>png256</code>, <code>png16</code> and -<code>pngmono</code> devices respectively provide 8-bit color, 4-bit color and -black-and-white for special needs. The <code>pngmonod</code> device is also a -black-and-white device, but the output is formed from an internal 8 bit grayscale -rendering which is then error diffused and converted down to 1bpp.</p> - -<p>The <code>png16malpha</code> and <code>pngalpha</code> devices are 32-bit RGBA color with transparency -indicating pixel coverage. The background is transparent unless -it has been explicitly filled. PDF 1.4 transparent files do not -give a transparent background with this device. The devices differ, in that the <code>pngalpha</code> device -enables Text and graphics anti-aliasing by default. We now recommend that people use the <code>png16malpha</code> -device in preference, and achieve any required antialiasing via the <code>DownScaleFactor</code> parameter, -as this gives better results in many cases.</p> - -<h4>Options</h4> - -<p>The <code>pngmonod</code>, <code>png16m</code>, <code>pnggray</code>, <code>png16malpha</code> and -<code>pngalpha</code> devices all respond to the following:</p> - -<blockquote> -<dl> -<dt><code>-dDownScaleFactor=</code><b><em>integer</em></b></dt> -<dd>This causes the internal rendering to be scaled down by the given (integer <= 8) factor before being output. For example, the following will produce -a 200dpi output png from a 600dpi internal rendering: -<blockquote> -<pre> - <kbd>gs -sDEVICE=png16m -r600 -dDownScaleFactor=3 -o tiger.png\ - examples/tiger.eps</kbd> -</pre> -</blockquote> -</dd> -</dl> -</blockquote> - -<p>The <code>pngmonod</code> device responds to the following option:</p> - -<blockquote> -<dl> -<dt><code>-dMinFeatureSize=</code><em>state</em> (0 to 4; default = 1)</dt> -<dd>This option allows a minimum feature size to be set; if any output pixel -appears on its own, or as part of a group of pixels smaller than -<code>MinFeatureSize</code> x <code>MinFeatureSize</code>, it will be expanded to -ensure that it does. This is useful for output devices that are high - resolution, but that have trouble rendering isolated pixels.</dd> - -<dd>While this parameter will accept values from 0 to 4, not all are fully -implemented. 0 and 1 cause no change to the output (as expected). 2 works -as specified. Values of 3 and 4 are accepted for compatibility, but -behave as for 2.</dd> -</dl> -</blockquote> - -<p>The <code>png16malpha</code> and <code>pngalpha</code> devices respond to the following option:</p> - -<blockquote> -<dl> -<dt><code>-dBackgroundColor=</code><b><em>16#RRGGBB</em></b> (RGB color, default white = 16#ffffff)</dt> -<dd>For the <code>png16malpha</code> and <code>pngalpha</code> devices only, -set the suggested background color in the PNG bKGD chunk. -When a program reading a PNG file does not support alpha -transparency, the PNG library converts the image using -either a background color if supplied by the program -or the bKGD chunk. -One common web browser has this problem, so when using -<code><body bgcolor="CCCC00"></code> on a web page -you would need to use <code>-dBackgroundColor=16#CCCC00</code> -when creating alpha transparent PNG images for use on the -page.</dd> -</dl> -</blockquote> - -<h4>Examples</h4> - -<p>Examples of how to use Ghostscript to convert postscript to PNG image files:</p> - -<blockquote> -<pre> - <kbd>gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -dGraphicsAlphaBits=4 \ - -sOutputFile=tiger.png examples/tiger.png</kbd> - - <kbd>gs -dSAFER -dBATCH -dNOPAUSE -r150 -sDEVICE=pnggray -dTextAlphaBits=4 \ - -sOutputFile=doc-%02d.png doc.pdf</kbd> -</pre> -</blockquote> - -<p>In commercial builds, the <code>png16m</code> device will accept a <code>-dDeskew</code> option to automatically detect/correct skew when generating output bitmaps.</p> - -<h3><a name="JFIF"></a>JPEG file format (JFIF)</h3> - -<p> -Ghostscript includes output drivers that can produce jpeg files -from postscript or pdf images. These are the <code>jpeg</code> and - <code>jpeggray</code> devices.</p> - -<p>Technically these produce <a href="http://www.ijg.org/">Independent JPEG Group</a> -JFIF (JPEG File Interchange Format) files, the common sort found on the web.</p> - -<p><strong>Please note</strong> that -JPEG is a compression method specifically intended for continuous-tone -images such as photographs, not for graphics, and it is therefore quite -unsuitable for the vast majority of page images produced with PostScript. -For anything other than pages containing simple images the lossy compression -of the jpeg format will result in poor quality output regardless of the input. -To learn more about the distinction, consult a reference about uses and abuses of JPEG, -such as the JPEG FAQ</p> - -<blockquote> -<a href="http://www.faqs.org/faqs/jpeg-faq/" class="offsite">http://www.faqs.org/faqs/jpeg-faq/</a> -</blockquote> - -<h4>Examples</h4> - -<p> -You can use the JPEG output drivers -- <code>jpeg</code> to produce -color JPEG files and <code>jpeggray</code> for grayscale JPEGs -- the -same as other file-format drivers: by specifying the device name and an -output file name, for example</p> - -<blockquote> -<pre><kbd>gs -sDEVICE=jpeg -sOutputFile=foo.jpg foo.ps</kbd></pre> -</blockquote> - -<h4>Options</h4> - -<p> -The JPEG devices support several special parameters to control the JPEG -"quality setting" (DCT quantization level).</p> - -<blockquote> -<dl> -<dt><code>-dJPEGQ=</code><b><em>N</em></b> (integer from 0 to 100, default 75)</dt> -<dd>Set the quality level <b><em>N</em></b> according to the widely used -IJG quality scale, which balances the extent of compression against the -fidelity of the image when reconstituted. Lower values drop more -information from the image to achieve higher compression, and therefore -have lower quality when reconstituted.</dd> - -<dt><code>-dQFactor=</code><b><em>M</em></b> (float from 0.0 to 1.0)</dt> -<dd>Adobe's QFactor quality scale, which you may use in place of -<code>JPEGQ</code> above. The QFactor scale is used by PostScript's -DCTEncode filter but is nearly unheard-of elsewhere.</dd> -</dl> -</blockquote> - -<p> -At this writing the default JPEG quality level of 75 is equivalent to -<code>-dQFactor=0.5</code>, but the JPEG default might change in the -future. There is currently no support for any additional JPEG -compression options, such as the other DCTEncode filter parameters. -</p> - - -<h3><a name="PNM"></a>PNM</h3> - -<p>The PNM (portable network map) family of formats are very simple -uncompressed image formats commonly used on unix-like systems. They -are particularly useful for testing or as input to an external conversion -utility.</p> - -<p>A wide variety of data formats and depths is supported. Devices include -<code>pbm - pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm - pksmraw</code>. -</p> - -<h3><a name="TIFF"></a>TIFF file formats</h3> - -<p><acronym>TIFF</acronym> is a loose collection of formats, now largely -superceded by <acronym>PNG</acronym> except in applications where backward -compatibility or special compression is required. The <acronym>TIFF</acronym> -file format is described in the -<a href="http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf" class="offsite">TIFF 6.0 Specification</a> -published by Adobe Systems Incorporated.</p> -<p>Note that, due to the structure of the TIFF format, writing TIFF output -requires that the target file be seekable. Writing to stdout, pipes or other -similar stream is not supported. Attempting to do so will generate an error. -</p> -<p> -There are two unrelated sets of TIFF drivers. There are five color TIFF -drivers that produce uncompressed output:</p> - -<blockquote> -<dl> -<dt><code>tiffgray</code></dt> -<dd>Produces 8-bit gray output.</dd> -<dt><code>tiff12nc</code></dt> -<dd>Produces 12-bit RGB output (4 bits per component).</dd> -<dt><code>tiff24nc</code></dt> -<dd>Produces 24-bit RGB output (8 bits per component).</dd> -<dt><code>tiff48nc</code></dt> -<dd>Produces 48-bit RGB output (16 bits per component).</dd> -<dt><code>tiff32nc</code></dt> -<dd>Produces 32-bit CMYK output (8 bits per component).</dd> -<dt><code>tiff64nc</code></dt> -<dd>Produces 64-bit CMYK output (16 bits per component).</dd> -<dt><a name="tiffsep"></a><code>tiffsep</code></dt> -<dd> -The <code>tiffsep</code> device creates multiple output files: a single 32 bit -composite CMYK file and multiple tiffgray files, one for each -separation (unless <code>-dNoSeparationFiles</code> is specified). If separation -files are being produced and more than one page is being generated, the output file -specification <b>must</b> include a format specifier (e.g <code>-o outfile-%d.tif</code>) -so that each page can have a uniquely named set of separation files. - -<p>The default compression is <code>lzw</code> but this may be overridden by -the <code>-sCompression=</code> option.</p> - -<p> -The file specified via the OutputFile command line parameter will contain -CMYK data. This data is based upon the CMYK data within the file plus -an equivalent CMYK color for each spot color. The equivalent -CMYK color for each spot color is determined using the alternate tint transform -function specified in the Separation and DeviceN color spaces. Since -this file is created based upon having color planes for each colorant, the -file will correctly represent the appearance of overprinting with spot colors.</p> - -<p> -File names for the separations for the CMYK colorants are created by appending -'.Cyan.tif', '.Magenta.tif' '.Yellow.tif' or '.Black.tif' to the -end of the file name specified via the OutputFile parameter. -File names for the spot color separation files are created by appending the -Spot color name in '(' and ').tif' to the filename.</p> -<p>Note that, while the name of the ink is case-sensitive, the filename may not be -(depending on the Operating System), so if a spot name matches one of the process -ink names, it will have the spot number included as part of the name (eg YELLOW0). -</p> - -<p> -If desired the file names for the spot color separation files can be created -by appending '.sn.tif' (where n is the spot color number, see below) to the end -of the file name specified via the OutputFile parameter. This change is a -compile time edit. To obtain this type of output the function -create_separation_file_name in gdevtsep.c should be called with a true value -for its use_sep_name parameter.</p> - -<p> -The <code>tiffsep</code> device will automatically recognize spot colors. In this -case their order is determined by when they are found in the input file. -The names of spot colors may be specified via the SeparationColorNames -device parameters.</p> - -<p> -Internally each spot color is assigned a spot color number. These -numbers start with 0 for the first spot color. The spot color -numbers are assigned in the same order as the names are printed to -stderr (see below). This order also matches the ordering in the -SeparationColorNames list, if this parameter is specified. The -spot color numbers are not affected by the SeparationOrder parameter.</p> - -<p> -If only a subset of the colorants for a file is desired, then the separations -to be output can be selected via the SeparationOrder -device parameter. When colorants are selected via the -SeparationOrder parameter, the composite CMYK output contains -the equivalent CMYK data only for the selected colorants.</p> - -<p> -NOTE: the composite CMYK output, because it uses the tint transformed -colour equivalents for any spot colours (see Postscript Language -Reference "Separation Color Spaces" and "DeviceN Color Spaces"), may -not produce an accurate preview, if the job uses overprinting.</p> - -<p> -The <code>tiffsep</code> device also prints the names of any spot colors -detected within a document to stderr. (stderr is also used for the -output from the bbox device.) For each spot color, the name of -the color is printed preceded by '%%SeparationName: '. This -provides a simple mechanism for users and external applications to be informed about -the names of spot colors within a document.</p> - -<p> -Generally Ghostscript will support a maximum of 64 process and spot -colors. The <code>tiffsep</code> device the <code>psdcmyk</code> device -and the <code>psdcmyk16</code> devices maintain rendered data -in a planar form with a maximum of 64 planes set by the definition of -GS_CLIENT_COLOR_MAX_COMPONENTS in the code. That is there can be up to -64 colorants accurately handled with overprint on a single page. If more -than 64 colorants are encountered, those beyond 64 will be mapped to CMYK using the -alternate tint transform.</p> - -<p> -When rendering a PDF document, Ghostscript can deteremine prior to rendering how -many colorants occur on a particular page. With Postscript, this is not possible -in general. To optimize for this, when rendering Postscript, it is possible to specify -at run-time the number of spot colorants you wish to have the device capable -of handling using the -dMaxSpots=N command option, where N is the number of spot -colorants that you wish to be able to handle and must be no more than the 64 minus the -number of process colors. For example, 60 or less for a CMYK device such as tiffsep. -If you specify more than -is needed, the document will render more slowly. The ideal case is to use -the same number as the maximum number of spot colorants that occur on a single page -of the document. If more spot colorants are encountered than is specified by --dMaxSpots, then a warning will be printed indicating that some spot colorants will -be mapped to CMYK using the alternate tint transform.</p> - -<p>The <code>tiffsep</code> device accepts a <code>-dBitsPerComponent=</code> -option, which may be set to 8 (the default) or 1. In 1bpp mode, the -device renders each component internally in 8 bits, but then converts -down to 1bpp with error diffusion before output as described below in -the <code>tiffscaled</code> device. No composite file is produced in -1bpp mode, only individual separations.</p> - -<p>The device also accepts the <code>-dDownScaleFactor= -dTrapX= -dTrapy=</code> and -<code>-sPostRenderProfile=</code> parameters as described below in the tiffscaled device, -and <code>-dMinFeatureSize=</code> in 1bpp mode.</p> - -<p>When <code>-dDownScaleFactor=</code> is used in 8 bit mode with the <code>tiffsep</code> -(and <code>psdcmyk</code>/<code>psdrgb</code>/<code>psdcmyk16</code>/<code>psdrgb16</code>) -device(s) 2 additional "special" ratios -are available, 32 and 34. 32 provides a 3:2 downscale (so from 300 to -200 dpi, say). 34 produces a 3:4 upscale (so from 300 to 400 dpi, say).</p> - -<p>In commercial builds, with 8 bit per component output, the <code>-dDeskew</code> option -can be used to automatically detect/correct skew when generating output bitmaps.</p> - -<p>The <code>tiffscaled</code> and <code>tiffscaled4</code> devices -can optionally use Even Toned Screening, rather than simple Floyd Steinberg -error diffusion. This patented technique gives better quality at the -expense of some speed. While the code used has many quality tuning -options, none of these are currently exposed. Any device author -interested in trying these options should contact Artifex for more -information. Currently ETS can be enabled using -dDownScaleETS=1.</p> - -</dd> -<dt><a name="tiffsep1"></a><code>tiffsep1</code></dt> -<dd> -The <code>tiffsep1</code> device creates multiple output files, one for each component -or separation color. The device creates multiple tiffg4 files (the compression -can be set using -sCompression= described below). The 1 bit per component -output is halftoned using the current screening set by 'setcolorscreen' -or 'sethalftone' which allows for ordered dither or stochastic threshold - array dither to be used. This is faster than error diffusion. - -<p> -The file specified via the OutputFile command line parameter will not be -created (it is opened, but deleted prior to finishing each page).</p> - -<p> -File names for the separations for the CMYK colorants are created by appending -'(Cyan).tif', '(Magenta).tif' '(Yellow).tif' or '(Black).tif' to the to the -end of the file name specified via the OutputFile parameter. File names -for the spot color separation files are created by appending the Spot color -name in '(' and ').tif' to the filename. -If the file name specified via the OutputFile parameter ends with the suffix -'.tif', then the suffix is removed prior to adding the component name in -'(' and ').tif'.</p> -</dd> - -<dt><a name="tiffscaled"></a><code>tiffscaled</code></dt> -<dd> -The <code>tiffscaled</code> device renders internally at the specified resolution to an -8 bit greyscale image. This is then scaled down by an integer scale factor -(set by <code>-dDownScaleFactor=</code> described below) and then error diffused to give -1bpp output. The compression can be set using -sCompression= as described -below.</dd> - - -<dt><a name="tiffscaled4"></a><code>tiffscaled4</code></dt> -<dd> -The <code>tiffscaled4</code> device renders internally at the specified resolution to an -8 bit cmyk image. This is then scaled down by an integer scale factor -(set by <code>-dDownScaleFactor</code>= described below) and then error diffused to give -4bpp cmyk output. The compression can be set using -sCompression= as described -below.</dd> - -<dt><a name="tiffscaled8"></a><code>tiffscaled8</code></dt> -<dd> -The <code>tiffscaled8</code> device renders internally at the specified resolution to an -8 bit greyscale image. This is then scaled down by an integer scale factor -(set by <code>-dDownScaleFactor</code>= described below). The compression can be set using --sCompression= as described below.</dd> - -<dt><a name="tiffscaled24"></a><code>tiffscaled24</code></dt> -<dd> -The <code>tiffscaled24</code> device renders internally at the specified resolution to a -24 bit rgb image. This is then scaled down by an integer scale factor -(set by <code>-dDownScaleFactor</code>= described below). The compression can be set using --sCompression= as described below. - -<p>In commercial builds, the <code>-dDeskew</code> option can be used to automatically detect/correct skew when generating output bitmaps.</p> -</dd> -<dt><a name="tiffscaled32"></a><code>tiffscaled32</code></dt> -<dd> -The <code>tiffscaled32</code> device renders internally at the specified resolution to a -32 bit cmyk image. This is then scaled down by an integer scale factor -(set by <code>-dDownScaleFactor</code>= described below). The compression can be set using --sCompression= as described below. - -<p>In commercial builds, the <code>-dDeskew</code> option can be used to automatically detect/correct skew when generating output bitmaps.</p> -</dd> -</dl> -</blockquote> - -<p> -The remaining TIFF drivers all produce black-and-white output with different -compression modes:</p> - -<blockquote> -<dl> -<dt><code>tiffcrle</code></dt> -<dd>G3 fax encoding with no EOLs</dd> -<dt><code>tiffg3</code></dt> -<dd>G3 fax encoding with EOLs</dd> -<dt><code>tiffg32d</code></dt> -<dd>2-D G3 fax encoding</dd> -<dt><code>tiffg4</code></dt> -<dd>G4 fax encoding</dd> -<dt><code>tifflzw</code></dt> -<dd>LZW-compatible (tag = 5) compression</dd> -<dt><code>tiffpack</code></dt> -<dd>PackBits (tag = 32773) compression</dd> -</dl> -</blockquote> - -<p>See the <code>AdjustWidth</code> option documentation below for important -information about these devices.</p> - -<h4>Options</h4> - -<p> -All TIFF drivers support creation of files that are comprised of more than a -single strip. Multi-strip files reduce the memory requirement on the reader, -since readers need only store and process one strip at a time. The -<code>MaxStripSize</code> parameter controls the strip size:</p> - -<blockquote> -<dl> -<dt><code>-dMaxStripSize=<em>N</em></code> (non-negative integer; default = 8192)</dt> -<dd>Set the maximum (uncompressed) size of a strip.</dd> -</dl> -</blockquote> - -<p> -The TIFF 6.0 specification, Section 7, page 27, recommends that the size of -each strip be about 8 Kbytes.</p> - -<p> -If the value of the <code>MaxStripSize</code> parameter is smaller than a -single image row, then no error will be generated, and the TIFF file will be -generated correctly using one row per strip. Note that smaller strip sizes -increase the size of the file by increasing the size of the StripOffsets and -StripByteCounts tables, and by reducing the effectiveness of the compression -which must start over for each strip.</p> - -<p> -If the value of MaxStripSize is 0, then the entire image will be a single strip.</p> - - -<p> -Since v. 8.51 the logical order of bits within a byte, FillOrder, tag = 266 is -controlled by a parameter:</p> - -<blockquote> -<dl> -<dt><code>-dFillOrder=<em>1 | 2 </em></code> (default = 1)</dt> -<dd>If this option set to 2 then pixels are arranged within a byte such that pixels -with lower column values are stored in the lower-order bits of the byte; otherwise -pixels are arranged in reverse order.</dd> -</dl></blockquote> - -<p>Earlier versions of Ghostscript always generated TIFF files with FillOrder = 2. -According to the TIFF 6.0 specification, Section 8, page 32, support of -FillOrder = 2 is not required in a Baseline TIFF compliant reader</p> - -<p> -The writing of BigTIFF format output files is controlled with the -<code>-dUseBigTIFF</code> parameter.</p> -<p> -Unfortunately, due the unpredictable size of compressed output, we cannot -automate the selection of BigTIFF, using it only when the output file -grows large enough to warrant it.</p> - -<blockquote> -<dl> -<dt><code>-dUseBigTIFF(=<em>false/true</em>)</code> (boolean, default: false)</dt> -<dd>Force use (or not) of BigTIFF format in output from TIFF devices</dd> -</dl> -</blockquote> - -<p> -The writing of the DateTime TAG can be controlled using the -<code>-dTIFFDateTime</code> parameter.</p> - -<blockquote> -<dl> -<dt><code>-dTIFFDateTime(=<em>true/false</em>)</code> (boolean, default: true)</dt> -<dd>Write or otherwise the DateTime TAG to the TIFF output file. Thus to disable -writing the TAG, use: <code>-dTIFFDateTime=false</code></dd> -</dl> -</blockquote> - -<p> -The compression scheme that is used for the image data can be set for all tiff -devices with:</p> - -<blockquote> - <dl> - <dt><code>-sCompression=<em>none | crle | g3 | g4 | lzw | pack</em></code></dt> - <dd>Change the compression scheme of the tiff device. - <code>crle</code>, <code>g3</code>, and <code>g4</code> may only be - used with 1 bit devices (including <code>tiffsep1</code>).</dd> - </dl> -</blockquote> - -<p> -For the <code>tiffsep</code> device, it changes the compression scheme -of the separation files and composite cmyk file (which is -<code>lzw</code> by default). It defaults to <code>g4</code> for the -<code>tiffsep1</code> device.</p> - -<p> -The black-and-white TIFF devices also provide the following parameters:</p> - -<blockquote><dl> -<dt><code>-dAdjustWidth=<em>state</em></code> (0, 1, or value; default = 1)</dt> -<dd>If this option is 1 then if the requested page width is in the range -of either 1680..1736 or 2000..2056 columns, set the page width to A4 -(1728 columns) or B4 (2048 columns) respectively. If this option is set -to a value >1 then the width is unconditionally adjusted to this value.</dd> - -<dd>This behavior is the default for all the fax based devices (i.e. all the black -and white devices except <code>tifflzw</code>, <code>tiffpack</code> and -<code>tiffscaled</code>). Pass <code>-dAdjustWidth=0</code> to force this behaviour -off.</dd> - -<dd>When using this option with <code>tiffscaled</code> it is the downsampled size -that triggers the adjustment.</dd> - -<dt><code>-dMinFeatureSize=<em>state</em></code> (0 to 4; default = 1)</dt> -<dd>This option allows a minimum feature size to be set; if any output pixel -appears on its own, or as part of a group of pixels smaller than -<code>MinFeatureSize</code> x <code>MinFeatureSize</code>, it will be expanded to -ensure that it does. This is useful for output devices that are high -resolution, but that have trouble rendering isolated pixels.</dd> - -<dd>While this parameter will accept values from 0 to 4, not all are fully -implemented. 0 and 1 cause no change to the output (as expected). 2 works -as specified. 3 and 4 currently expand pixels correctly horizontally, but -only expand vertically to the 2 pixel size.</dd> - -<dd>The mechanism by which <code>MinFeatureSize</code> is implemented for -<code>tiffscaled</code> is different, in that it is done as part of the error -diffusion. Values of 0 to 2 work as expected, but values 3 and 4 (while -accepted for compatibility) will behave as for 2.</dd> - -</dl></blockquote> - -<p> -The <code>tiffscaled</code>, <code>tiffscaled4</code>, <code>tiffscaled8</code>, -<code>tiffscaled24</code> and <code>tiffscaled32</code> TIFF -drivers also provide the following two parameters:</p> - -<blockquote><dl> -<dt><code>-dDownScaleFactor=<em>factor</em></code> (integer <= 8; default = 1)</dt> -<dd>If this option set then the page is downscaled by the given factor on both -axes before error diffusion takes place. For example rendering with -<code>-r600</code> and then specifying <code>-dDownScaleFactor=3</code> will produce -a 200dpi image.</dd> -</dl></blockquote> - -<blockquote><dl> -<dt><code>-sPostRenderProfile=<em>path</em></code> (path to an ICC profile)</dt> -<dd>If this option set then the page will be color transformed using that -profile <b>after</b> downscaling. -<p> -This is useful when the file uses overprint to separately paint to some -subset of the C, M, Y, and K colorants, but the final CMYK is to be color -corrected for printing or display.</p> -</dd> -</dl></blockquote> - -<p> -The <code>tiffsep</code> TIFF device also provide this parameter:</p> - -<blockquote><dl> -<dt><code>-dPrintSpotCMYK=<em>boolean</em></code> defaults to false. When set to true -the device will print (to stdout) the name of each ink used on the page, and the CMYK -values which are equivalent to 100% of that ink. The values are 16-bits ranging from 0 -to 32760.</dt><dd></dd> -</dl></blockquote> - -<a name="TIFF_trapping"></a> -<p>The <code>tiffsep</code> device (along with the <code>tiffscaled32</code> and -<code>psdcmyk</code> devices) can perform rudimentary automatic bitmap -'trapping' on the final rendered bitmap. This code is disabled by default; see -the <a href="#trapping_patent_note">note</a> below as to why.</p> - -<p>Trapping is a process whereby the output is adjusted to minimise the -visual impact of offsets between each printed plane. Typically this involves -slightly extending abutting regions that are rendered in different inks. The -intent of this is to avoid the unsightly gaps that might be otherwise be -revealed in the final printout if the different color plates do not exactly -line up.</p> - -<p>This trapping is controlled by 3 device parameters. Firstly the maximum -X and Y offsets are specified using <code>-dTrapX=N</code> and <code>-dTrapY=N</code> -(where <code>N</code> is a figure in pixels, before the downscaler is applied).</p> - -<p>The final control is to inform the trapping process in what order inks -should be processed, from darkest to lightest. For a typical CMYK device -this order would be [ 3 1 0 2 ] (K darker than M darker than C darker than Y). -This is the default. In the case where CMYK + spots are used, the code -defaults to assuming that the spots are lighter than the standard colours -and are sent darkest first (thus [ 3 1 0 2 4 5 6 ... ]).</p> - -<p>To override these defaults, the <code>TrapOrder</code> parameter can be used, for -example:</p> - -<blockquote><code> - gs -sDEVICE=psdcmyk -dTrapX=2 -dTrapY=2 -o out.psd -c "<< /TrapOrder [ 4 5 3 1 0 2 ] >> setpagedevice" -f examples\tiger.eps -</code></blockquote> - -<h4><a name="trapping_patent_note"></a>Trapping patents</h4> - -<p>Trapping is an technology area encumbered by many patents. We -believe that the last of these has now lapsed, and so have enabled -the code by default.</p> - -<h3><a name="fax"></a>FAX</h3> - -<p> -Ghostscript supports a variety of fax encodings, both encapsulated in -<acronym>TIFF</acronym> (see above) and as raw files. The later case is -described here. -</p> - -<p> -The fax devices are <code>faxg3</code>, <code>faxg32d</code> and <code>faxg4</code>. -</p> - -<p> -The fax devices support the <code>MinFeatureSize</code> parameter as defined in -the TIFF device section. -</p> - -<h3><a name="BMP"></a>BMP</h3> - -<p> -BMP is a simple uncompressed image format commonly used on MS Windows. -It is supported by the devices <code>bmpmono bmpgray bmpsep1 - bmpsep8 bmp16 bmp256 bmp16m bmp32b</code>. -</p> - -<h3><a name="PCX"></a>PCX</h3> - -<p> -PCX is an image format sometimes used on MS Windows. It has some support -for image compression and alternate color spaces, and so can be a useful -way to output CMYK. -It is supported by the <code>pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk</code> -series of devices. -</p> - -<h3><a name="PSD"></a>PSD</h3> - -<p> -PSD is the image format used by Adobe Photoshop. -It is supported by the <code>psdcmyk</code>, <code>psdrgb</code> -<code>psdcmyk16</code> and <code>psdrgb16</code> devices. -Of special interest with the <code>psdcmyk</code> and <code>psdcmyk16</code> devices is that they support spot -colors. <a href="#tiffsep">See the comments under the <code>tiffsep</code> and <code>tiffsep1</code> -device about the maximum number of spot colors supported by Ghostscript</a></p> -<p> -The <code>psdcmyk16</code> and <code>psdrgb16</code> devices are essentially the same -as the <code>psdcmyk</code> and <code>psdrgb</code> devices except they provide 16 bit output. -</p> -<p> -The <code>psdcmykog</code> device produces PSD files with 6 components: -Cyan, Magenta, Yellow, blacK, Orange, and Green. This device does not support the -dDownScaleFactor= -option (see below), instead it always scales down by a factor of two.</p> - -<p> -These devices support the same -dDownScaleFactor= ratios as <code>tiffsep</code>. -The <code>psdcmyk</code> device supports the same trapping options as <code>tiffsep</code> -(but see <a href="#trapping_patent_note">this note</a>).</p> - -<p> -NOTE: The PSD format is a single image per file format, so you must use the "%d" -format for the "OutputFile" (or "-o") file name parameter (see -<a href="Use.htm#One_page_per_file">One_page_per_file</a> for details). An attempt -to output multiple pages to a single PSD file (i.e. without the "%d" format) will -result in an <code>ioerror</code> Postscript error.</p> - -<p>In commercial builds, for the <code>psdcmyk</code> and <code>psdrgb</code> devices, the <code>-dDeskew</code> option can be used to automatically detect/correct skew when generating output bitmaps.</p> - -<h3><a name="PDFimage"></a>PDF image output</h3> - -<p> -These devices render input to a bitmap (or in the case of PCLm multiple bitmaps) then wraps -the bitmap(s) up as the content of a PDF file. For PCLm there are some additional rules regarding -headers, extra content and the order in which the content is written in the PDF file. -</p> -<p> -The aim is to support the PCLm mobile printing standard, and -to permit production of PDF files from input where the graphics -model differs significantly from PDF (eg PCL and RasterOPs). -</p> -<p> -There are five devices named pdfimage8, pdfimage24, pdfimage32, pclm and pclm8. These produce valid -PDF files with a colour depth of 8 (Gray), 24 (RGB) or 32 (CMYK), the pclm device only supports 24-bit RGB -and the pclm8 device only supports 8-bit gray. -These are all implemented as 'downscale' devices, which means they can implement page level -anti-aliasing using the <code>-dDownScaleFactor</code> switch. -</p> - -<blockquote> -<dl> -<dt><code>-dDownScaleFactor=</code><b><em>integer</em></b></dt> -<dd>This causes the internal rendering to be scaled down by the given (integer <= 8) factor before being output. For example, the following will produce - a PDF containing a 200dpi output from a 600dpi internal rendering:</dd></dl> -<blockquote> -<pre> - <kbd>gs -sDEVICE=pdfimage8 -r600 -dDownScaleFactor=3 -o tiger.pdf\ - examples/tiger.eps</kbd> -</pre> -</blockquote> -</blockquote> - -<p>In commercial builds, the <code>-dDeskew</code> option can be used to automatically detect/correct skew when generating the output file.</p> - -<p> -The type of compression used for the image data can also be selected using the <code>-sCompression</code> switch. -Valid compression types are <code>None</code>, <code>LZW</code>, <code>Flate</code>, <code>JPEG</code> -and <code>RLE</code>.Note that LZW is not supported on PCLm (not valid) and None is only supported -on PCLm for debugging purposes. -</p> -<p> -For JPEG compression the devices support both the JPEGQ and QFactor switches as documented for the <a href="#JFIF">JPEG</a> file format device. -</p> -<p> -In addition, the PCLm device supports some other parameters. Firstly, the -<code>-dStripHeight</code> switch to set the vertical height -of the strips of image content, as required by the specification. -</p> -<p>Secondly, the standard postscript <code>-dDuplex</code> and -<code>-dTumble</code>switches are supported, in that if both are -set to true, every verso page (i.e. all even pages) will be -rotated by 180 degrees.</p> - -<p>As an extension to this, a <code>-dTumble2</code> parameter is -also supported that will add an additional X-axis flip for every -verso page. Thus <code>-dDuplex=true -dTumble=false -dTumble2=true</code> -will result in verso pages being flipped horizontally, and -<code>-dDuplex=true -dTumble=true -dTumble2=true</code> will result -in verso pages being flipped vertically.</p> - -<hr> - -<p> -In addition to raster image files, Ghostscript supports output in a number -of 'high-level' formats. These allow Ghostscript to preserve (as much as -possible) the drawing elements of the input file maintaining flexibility, -resolution independence, and editability.</p> - -<hr> - -<h2><a name="OCR-Devices"></a>Optical Character Recognition (OCR) devices</h2> - -<h3><a name="OCR"></a>OCR text output</h3> - -<p> - These devices render internally in 8 bit greyscale, and then - feed the resultant image into an OCR engine. Currently, we - are using the Tesseract engine. Not only is this both free - and open source, it gives very good results, and supports - a huge number of languages/scripts. -</p> -<p> - The Tesseract engine relies on files to encapsulate each - language and/or script. These "traineddata" files - are available in different forms, including <a href="http://github.com/tesseract-ocr/tessdata_fast">fast</a> - and <a href="http://github.com/tesseract-ocr/tessdata_best">best</a> variants. - Alternatively, people can train their own data using the - standard Tesseract tools. -</p> -<p> - These files are looked for from a variety of places. -</p> -<ul> - <li>Firstly, files will be searched for in the directory given by the - environment variable TESSDATA_PREFIX. - <li>Next, they will be searched for within the ROM filing system. Any - files placed in "tessdata" will be included within the ROM - filing system in the binary for any standard (COMPILE_INITS=1) build. - <li>Next, files will be searched for in the configured 'tessdata' path. On - Unix, this can be specified at the configure stage using - '--with-tessdata=<path>' (where <path> is a list of - directories to search, separated by ':' (on Unix) or ';' (on Windows)). - <li>Finally, we resort to searching the current directory. -</ul> -<p> - Please note, this pattern of directory searching differs from the original - release of the OCR devices. -</p> -<p> - By default, the OCR process defaults to looking for English text, - using "eng.traineddata". This can be changed by using the - <code>-sOCRLanguage=</code> switch; -</p> -<blockquote> -<dl> -<dt><code>-sOCRLanguage=</code><b><em>language</em></b></dt> -<dd>This sets the trained data sets to use within the Tesseract - OCR engine. For example, the following will use English and - Arabic:</dd></dl> -<blockquote> -<pre> - <kbd>gs -sDEVICE=ocr -r200 -sOCRLanguage="eng+ara" -o out.txt\ - zlib/zlib.3.pdf</kbd> -</pre> -</blockquote> -</blockquote> -<p> - The first device is named ocr. It extracts data as unicode codepoints - and outputs them to the device as a stream of UTF-8 bytes. -</p> -<p> - The second device is named hocr. This extracts the data in - <a href="wikipedia.org/wiki/HOCR">hOCR</a> format. -</p> -<p> - These devices are implemented as downscaling devices, so the - standard parameters can be used to control this process. It - may seem strange to use downscaling on an image that is not - actually going to be output, but there are actually good reasons - for this. Firstly, the higher the resolution, the slower the - OCR process. Secondly, the way the Tesseract OCR engine works - means that anti-aliased images perform broadly as well as the - super-sampled image from which it came. -</p> - -<h3><a name="PDFocr"></a>PDF image output (with OCR text)</h3> - -<p> - These devices do the same render to bitmap and wrap as a PDF process as - the <a name="PDFimage">PDFimage</a> devices above, but with the addition - of an OCR step at the end. The OCR'd text is overlaid "invisibly" - over the images, so searching and cut/paste should still work. -</p> -<p> - The OCR engine being used is Tesseract. For information on this - including how to control what language data is used, see the <a href="OCR"> - OCR devices</a> section above. -</p> -<p> - There are three devices named pdfocr8, pdfocr24 and pdfocr32. These - produce valid PDF files with a colour depth of 8 (Gray), 24 (RGB) or - 32 (CMYK). -</p> -<p> - These devices accept all the same flags as the <a name="PDFimage">PDFimage</a> - devices described above. -</p> -<p> - -<h3><a name="PDFwriteocr"></a>Vector PDF output (with OCR Unicode CMaps)</h3> -<p> -The pdfwrite device has been augmented to use the OCR engine to analyse text -(not images!) in the input stream, and derive Unicode code points for it. -That information can then be used to create ToUnicode CMaps which are attached -to the Font (or CIDFont) objects embedded in the PDF file. -</p> -<p> -Fonts which have ToUnicode CMaps can be reliably (limited by the accuracy of -the CMap) used in search and copy/paste functions, as well as text extraction -from PDF files. Note that OCR is not a 100% perfect process; it is possible -that some text might be misidentified. -</p> -<p> -OCR is a slow operation! In addition it can (for Latin text at least) sometimes -be preferable not to add ToUnicode information which may be incorrect, but instead -to use the existing font Encoding. For English text this may give better results. -</p> -<p>For these reasons the OCR functionality of pdfwrite can be controlled by using a new -parameter <code>-sUseOCR</code>. This has three possible values; -</p> -<dl> -<dt><code>-sUseOCR=</code><b><em>string</em></b></dt> - - <dt>Never</dt><dd>Default - don't use OCR at all even if support is built-in.</dd> - <dt>AsNeeded</dt><dd>If there is no existing ToUnicode information, use OCR.</dd> - <dt>Always</dt><dd>Ignore any existing information and always use OCR.</dd> - -</dl> -</p> - -<hr> - -<h2><a name="High-level"></a>High-level devices</h2> - -<h3><a name="PDF"></a>PDF writer</h3> - -<p>The <code>pdfwrite</code> device outputs PDF.</p> - -<h3><a name="PS"></a>PS2 writer</h3> - -<p>The <code>ps2write</code> device outputs postscript language level 2. -It is recommnded that this device is used for PostScript output. -There is no longer any support for creating PostScript level 1 output.</p> - -<h3><a name="EPS"></a>EPS writer</h3> - -<p>The <code>eps2write</code> device outputs encapsulated postscript.</p> -<h3><a name="PXL"></a>PXL</h3> - -<p>The <code>pxlmono</code> and <code>pxlcolor</code> devices output HP PCL-XL, -a graphic language understood by many recent laser printers.</p> - - -<h3><a name="TXT"></a>Text output</h3> - -<p> The txtwrite device will output the text contained in the original -document as Unicode.</p> - -<p> Please refer to -<a href="VectorDevices.htm">VectorDevices.htm</a> for documentation on the -device options for these devices. -</p> - -<hr> - -<h2><a name="Display_devices"></a>Display Devices</h2> - -<p> -Ghostscript is often used for screen display of postscript and pdf documents. -In many cases, a client or 'viewer' application calls the Ghostscript engine -to do the rasterization and handles the display of the resulting image itself, -but it is also possible to invoke Ghostscript directly and select an output -device which directly handles displaying the image on screen.</p> - -<p> -This section describes the various display-oriented devices that are available -in Ghostscript.</p> - -<h3><a name="x11_devices"></a>X Window System</h3> - -<p> -Perhaps the most common use of of a display device is with the X Window System -on unix-like systems. It is the default device on the command line client on -such systems, and is used more creatively by the gv client application.</p> - -<p> -The available devices are:</p> - -<dl> -<dt><b>x11</b></dt> -<dd>This is the default device, handling display on X11R6.</dd> - -<dt><b>x11alpha</b></dt> -<dd>This is the <code>x11</code> device, but with antialiasing. It is equivalent to -invoking the <code>x11</code> device with the options <code>-dGraphicsAlphaBits=4 --dTextAlphaBits=4 -dMaxBitmap=50000000</code>.</dd> - -<dt><b>x11cmyk</b></dt> -<dd>This device rasterizes the image in the CMYK color space, then flattens -it to RGB for display. It's intended for testing only.</dd> - -<dt><b>x11mono</b></dt> -<dd>This is a strict black-and-white device for 1-bit monochrome displays.</dd> - -<dt><b>x11gray2</b></dt> -<dd>This is a device for 2 bpp (4-level) monochrome displays.</dd> - -<dt><b>x11gray4</b></dt> -<dd>This is a device for 4 bpp (16-level) monochrome displays.</dd> -</dl> - -<p>On Mac OS X as of 10.6, the X server (XQuartz) only supports color depth -15 and 24. Depth 15 isn't well-tested, and it may be desirable, for serious -use, to switch to depth 24 with:</p> - -<blockquote><code> -defaults write org.x.X11 depth 24 -</code></blockquote> - -<h3><a name="display_device"></a>display device (MS Windows, OS/2, gtk+)</h3> -<p> -The <code>display</code> device is used by the MS Windows, -OS/2 and the gtk+ versions of ghostscript. -</p> - -<h4>Options</h4> - -<p>The display device has several user settable options.</p> - -<blockquote> -<dl> -<dt><code>-dDisplayFormat=</code><b><em>N</em></b> (integer bit-field)</dt> -<dd>Some common values are 16#30804 for Windows RGB, 16#804 for gtk+ RGB, -16#20101 for Windows monochrome, 16#102 for gtk+ monochrome, -16#20802 grayscale, 16#20808 for CMYK, 16#a0800 for separations. -<p> -The bit fields are: -</p> -<ul> -<li> native (1), gray (2), RGB (4), CMYK (8), or separation (80000) -color spaces.</li> -<li> unused first byte (40) or last byte (80).</li> -<li> 1 (100), 4 (400), or 8 (800) bits/component.</li> -<li> bigendian (00000 = RGB) or littleendian (10000 = BGR) order.</li> -<li> top first (20000) or bottom first (00000) raster.</li> -<li> 16 bits/pixel with 555 (00000) or 565 (40000) bitfields.</li> -</ul> -<p>For more details, see the <a href="API.htm#display">Ghostscript -Interpreter API.</a></p> -</dd> -<dt><code>-dDisplayResolution=</code><b><em>DPI</em></b></dt> -<dd>Set the initial resolution resolution for the display device. -This is used by the Windows clients to set the display device -resolution to the Windows display logical resolution. -This can be overriden by the command line option -<code>-r<em>DPI</em></code>.</dd> -</dl> - -</blockquote> - -<p>When using the separation color space, the following options may be set -using setpagedevice, as described in the PostScript Language Reference:</p> - -<blockquote> -<dl> -<dt><code>SeparationColorNames</code></dt> -<dd>An array giving the names of the spot colors</dd> - -<dt><code>SeparationOrder</code></dt> -<dd>An array giving the names and order of the colorants - to be output.</dd> -</dl> -</blockquote> - - -<hr> - -<h2><a name="IJS"></a>IJS - Inkjet and other raster devices</h2> - -<p> -IJS is a relatively new initiative to improve the quality and ease of -use of inkjet printing with Ghostscript. Using IJS, you can add new -drivers, or upgrade existing ones, without recompiling Ghostscript. -All driver authors are encouraged to adapt their drivers for IJS, and -if there is an IJS driver available for your printer, it should be -your first choice. -</p> - -<p>Please see the <a href="http://www.linuxprinting.org/ijs/">IJS web -page</a> for more information about IJS, including a listing of -IJS-compatible drivers. -</p> - -<p> -A typical command line for IJS is: -</p> - -<blockquote> -<code> -gs -dSAFER -sDEVICE=ijs -sIjsServer=hpijs - -sDeviceManufacturer=HEWLETT-PACKARD -sDeviceModel='DESKJET 990' - -dIjsUseOutputFD -sOutputFile=/dev/usb/lp1 -dNOPAUSE -- - examples/tiger.eps -</code> -</blockquote> - - -<p> -Individual IJS command line parameters are as follows: -</p> - -<dl> -<dt><code>-sIjsServer=</code><em>{path}</em></dt> -<dd>Sets the pathname for the IJS server (ie printer driver). -Ghostscript will spawn a new process for this driver, and communicate -with it using the IJS protocol. The pathname need not be absolute, -as the PATH environment variable is searched, but it's probably a good -idea for robustness and security. Note also that if -dSAFER is not -specified, it's possible for PostScript code to set this parameter, -so it can cause arbitrary code to be executed. See the section on <a -href="Use.htm#Security">Security</a> for more information.</dd> -</dl> - -<dl> -<dt><code>-sDeviceManufacturer=</code><em>{name}</em></dt> -<dt><code>-sDeviceModel=</code><em>{name}</em></dt> -<dd>These parameters select the device according to IEEE-1284 standard -device ID strings. In general, consult the documentation for the -driver to find the appropriate settings. Note that, if the value -contains a space, you'll want to quote the value in your shell, as -in the example above.</dd> -</dl> - -<dl> -<dt><code>-sIjsParams=</code><em>{params}</em></dt> -<dd>This parameter allows you to set arbitrary IJS parameters on -the IJS driver. The format is a comma-separated list of -<code>key=value</code> pairs. If it is necessary to send a -value containing a comma or backslash, it can be escaped with -a backslash. Thus, <code>'-sIjsParams=Foo=bar,Baz=a\,b'</code> sets -the parameter Foo to "bar", and Baz to "a,b".</dd> -</dl> - -<dl> -<dt><code>-dIjsUseOutputFD</code></dt> -<dd>This flag indicates that Ghostscript should open the output file -and pass a file descriptor to the server. If not set, Ghostscript -simply passes the filename set in OutputFile to the server. In most -cases, this flag won't matter, but if you have a driver which works -only with OutputFD (such as hpijs 1.0.2), or if you're using the --sOutputFile="|cmd" syntax, you'll need to set it.</dd> -</dl> - -<dl> -<dt><code>-dBitsPerSample=</code><em>N</em></dt> -<dd>This parameter controls the number of bits per sample. The -default value of 8 should be appropriate for most work. For monochrome -images, use -dBitsPerSample=1.</dd> -</dl> - -<p>Generic Ghostscript options that are particularly relevant for IJS -are summarized below: -</p> - -<dl> -<dt><code>-r</code><em>number</em></dt> -<dt><code>-r</code><em>number1</em><code>x</code><em>number2</em></dt> -<dd>Sets the resolution, in dpi. If the resolution is not specified, -Ghostscript queries the IJS server to determine the preferred resolution. -When the resolution is specified, it overrides the value (if any) -preferred by the IJS server.</dd> -</dl> - -<dl> -<dt><code>-dDuplex</code></dt> -<dt><code>-dTumble</code></dt> -<dd>These flags enable duplex (two-sided) printing. Tumble controls -the orientation. When Tumble is false, the pages -are oriented suitably at the left or right. When Tumble is true, -the pages are oriented suitably for binding at the top or -bottom.</dd> -</dl> - -<dl> -<dt><code>-sProcessColorModel=</code><em>{name}</em></dt> -<dd>Use this flag to select the process color model. Suitable values -include DeviceGray, DeviceRGB, and DeviceCMYK.</dd> -</dl> - -<h3>Building IJS</h3> - -<p> IJS is included by default on Unix gcc builds, and also in -autoconf'ed builds. Others may need some makefile tweaking. First, -make sure the IJS device is selected:</p> - -<blockquote> -DEVICE_DEVS2=$(DD)ijs.dev -</blockquote> - -<p> Next, make sure that the path and execution type are set in -the top level makefile. The values for Unix are as follows:</p> - -<blockquote> -IJSSRCDIR=ijs -IJSEXECTYPE=unix -</blockquote> - -<p> At present, "unix" and "win" are the only supported values for -IJSEXECTYPE. If neither sounds appropriate for your system, it's -possible that more porting work is needed.</p> - -<p> Last, make sure that ijs.mak is included in the top level makefile. -It should be present right after the include of icclib.mak.</p> - -<p> IJS is not inherently platform-specific. We're very much interested -in taking patches from people who have ported it to non-mainstream -platforms. And once it's built, you won't have to recompile Ghostscript -to support new drivers!</p> -<hr> -<h2><a name="Rinkj"></a>Rinkj - Resplendent inkjet driver</h2> - -<p>The Rinkj driver is an experimental new driver, capable of driving -some Epson printers at a very high level of quality. It is not -currently recommended for the faint of heart.</p> - -<p>You will need to add the following line to your makefile:</p> - -<blockquote> -DEVICE_DEVS2=$(DD)rinkj.dev -</blockquote> - -<p>Most of the configuration parameters, including resolution, choice -of printer model, and linearization curves, are in a separate setup -file. In addition, we rely heavily on an ICC profile for mapping -document colors to actual device colors.</p> - -<p>A typical command line invocation is:</p> - -<blockquote><code> -gs -r1440x720 -sDEVICE=rinkj -sOutputFile=/dev/usb/lp0 - -sSetupFile=lib/rinkj-2200-setup -sProfileOut=2200-cmyk.icm - -dNOPAUSE -dBATCH file.ps -</code></blockquote> - -<p> -Individual Rinkj command line parameters are as follows: -</p> - -<dl> -<dt><code>-sSetupFile=</code><em>{path}</em></dt> -<dd>Specifies the path for the setup file.</dd> - -<dt><code>-sProfileOut=</code><em>{path}</em></dt> -<dd>Specifies the path for the output ICC profile. This profile should -be a <i>link</i> profile, mapping the ProcessColorModel (DeviceCMYK by -default) to the device color space.</dd> -</dl> - -<p>For 6- and 7-color devices, the target color space for the output -profile is currently a 4-component space. The conversion from this -into the 6- or 7-color space (the "ink split") is done by lookup -tables in the setup file.</p> - -<p>Setup files are in a simple "Key: value" text format. Relevant keys -are:</p> - -<dl> -<dt><code>Manufacturer:</code><em>{name}</em></dt> -<dt><code>Model:</code><em>{name}</em></dt> -<dd>The manufacturer and model of the individual device, using the -same syntax as IEEE printer identification strings. Currently, the -only supported manufacturer string is "EPSON", and the only supported -model strings are "Stylus Photo 2200" and "Stylus Photo 7600".</dd> - -<dt><code>Resolution:</code><em>{x-dpi}</em>x<em>{y-dpi}</em></dt> -<dd>The resolution in dpi. Usually, this should match the -Ghostscript resolution set with the <code>-r</code> switch. Otherwise, -the page image will be scaled.</dd> - -<dt><code>Dither:</code><em>{int}</em></dt> -<dd>Selects among variant dither options. Currently, the choices are -<code>1</code> for one-bit dither, and <code>2</code>, for a 2-bit variable -dot dither.</dd> - -<dt><code>Aspect:</code><em>{int}</em></dt> -<dd>Controls the aspect ratio for highlight dot placement. Valid -values are <code>1</code>, <code>2</code>, and <code>4</code>. For best results, -choose a value near the x resolution divided by the y resolution. For -example, if resolution is 1440x720, aspect should be 2.</dd> - -<dt><code>Microdot:</code><em>{int}</em></dt> -<dd>Chooses a microdot size. On EPSON devices, this value is passed -directly through to the "ESC ( e" command. See EPSON documentation -for further details (see, I <em>told</em> you this wasn't for the -faint of heart).</dd> - -<dt><code>Unidirectional:</code><em>{int}</em></dt> -<dd>Enables (1) or disables (0) unidirectional printing, which is -slower but possibly higher quality.</dd> - -<dt><code>AddLut:</code><em>{plane}</em></dt> -<dd>Adds a linearization look-up table. The plane is one of -"CcMmYKk". The lookup table data follows. The line immediately -following AddLut is the number of data points. Then, for each data -point is a line consisting of two space-separated floats - the output -value and the input value. If more than one LUT is specified for a -single plane, they are applied in sequence.</dd> -</dl> - -<p>A typical setup file is supplied in <code>lib/rinkj-2200-setup</code>. -It is configured for the 2200, but can be adapted to the 7600 just by -changing the "Model" line.</p> - -<p>A known issue with this driver is poor support for margins and -page size. In some cases, this will cause an additional page to be -ejected at the end of a job. You may be able to work around this by -supplying a cut-down value for <code>-dDEVICEHEIGHTPOINTS</code>, for -example 755 for an 8.5x11 inch page on the EPSON 2200.</p> -<hr> -<h2><a name="HP_ijs"></a>HP Deskjet official drivers</h2> - -<p> -HP provides official drivers for many of their Deskjet printer models. -In order to use these drivers, you will need the HP Inkjet Server as -well as Ghostscript, available from <a -href="http://hpinkjet.sourceforge.net">http://hpinkjet.sourceforge.net</a>. -This version of Ghostscript includes the patch from version 0.97 of -the hpijs software. If you are installing hpijs from an RPM, you will -only need the hpijs RPM, not the Ghostscript-hpijs one, as the code -needed to work with hpijs is already included.</p> - -<p> -Note that newer version of the hpijs drivers support the IJS protocol. -If you can, you should consider using the ijs driver instead. Among -other things, the hpijs Ghostscript driver is Unix-only, and is untested -on older Unix platforms.</p> - -<p> -As of the 0.97 version, hpijs supports the following printer models:</p> - -<dl><dt><b>e-Series:</b></dt> -<dd>e-20</dd> -<dt><b>DeskJet 350C Series:</b></dt> -<dd>350C</dd> -<dt><b>DeskJet 600C Series:</b></dt> -<dd>600C, 660C, 670/672C, 670TV, 680/682C</dd> -<dt><b>DeskJet 600C Series Photo:</b></dt> -<dd>610/612C, 640/648C, 690/692/693/694/695/697C</dd> -<dt><b>DeskJet 630C Series:</b></dt> -<dd>630/632C</dd> -<dt><b>DeskJet 800C Series:</b></dt> -<dd>810/812C, 830/832C, 840/842/843C, 880/882C, 895C</dd> -<dt><b>DeskJet 900C Series, PhotoSmart::</b></dt> -<dd>930/932C, 950/952C, 970C, PhotoSmart 1000/1100</dd> -<dt><b>DeskJet 990C, PhotoSmart:</b></dt> -<dd>960C, 980C, 990C, PhotoSmart 1215/1218</dd> - -</dl> - - <p>You will need to add the following line to your makefile:</p> - -<blockquote> -DEVICE_DEVS2=$(DD)DJ630.dev $(DD)DJ6xx.dev $(DD)DJ6xxP.dev $(DD)DJ8xx.dev $(DD)DJ9xx.dev $(DD)DJ9xxVIP.dev $(DD)AP21xx.dev -</blockquote> - -<p> -Please see <a -href="http://hpinkjet.sourceforge.net">http://hpinkjet.sourceforge.net</a> -for more information about this driver. Thanks to the folks at HP, -especially David Suffield for making this driver available and working to -integrate it with Ghostscript. -</p> -<hr> -<h2><a name="gimp-print"></a>Gimp-Print driver collection</h2> - -<p> -The Gimp-Print project provides a large collection of printer drivers -with an IJS interface. Please see their -<a href="http://gimp-print.sourceforge.net/" class="offsite">website</a> -for details. -</p> - -<hr> -<h2><a name="Win"></a>MS Windows printers</h2> - -<p> -This section was written by Russell Lang, the author of Ghostscript's -MS Windows-specific printer driver, and updated by -<a href="mailto:Pierre.Arnaud@opac.ch">Pierre Arnaud</a>, -the current maintainer. -</p> - -<p> -The <code>mswinpr2</code> device uses MS Windows printer drivers, and -thus should work with any printer with device-independent bitmap (DIB) -raster capabilities. The printer resolution cannot be selected directly -using PostScript commands from Ghostscript: use the printer setup in the -Control Panel instead. It is however possible to specify a maximum resolution -for the printed document (see below). -</p> - -<p> -If no Windows printer name is specified in <code>-sOutputFile</code>, -Ghostscript prompts for a Windows printer using the standard Print Setup -dialog box. You must set the orientation to Portrait and the page size to -that expected by Ghostscript; otherwise the image will be clipped. -Ghostscript sets the physical device size to that of the Windows printer -driver, but it does not update the PostScript clipping path. -</p> - -<p> -If a Windows printer name is specified in <code>-sOutputFile</code> using -the format <code>"%printer%printer_name"</code>, for instance -</p> - -<blockquote><code> -gs ... -sOutputFile="%printer%Apple LaserWriter II NT" -</code></blockquote> - -<p> -then Ghostscript attempts to open the Windows printer without prompting -(except, of course, if the printer is connected to <code>FILE:</code>). -Ghostscript attempts to set the Windows printer page size and orientation -to match that expected by Ghostscript, but doesn't always succeed. It uses -this algorithm: -</p> - -<ol> -<li>If the requested page size matches one of the Windows standard page -sizes +/- 2mm, request that standard size.</li> - -<li>Otherwise if the requested page size matches one of the Windows -standard page sizes in landscape mode, ask for that standard size in -landscape.</li> - -<li>Otherwise ask for the page size by specifying only its dimensions.</li> - -<li>Merge the requests above with the defaults. If the printer driver -ignores the requested paper size, no error is generated: it will print on -the wrong paper size.</li> - -<li>Open the Windows printer with the merged orientation and size.</li> -</ol> - -<p> -The Ghostscript physical device size is updated to match the Windows -printer physical device. -</p> - -<h3><a name="Win_properties"></a>Supported command-line parameters</h3> - -<p> -The <code>mswinpr2</code> device supports a limited number of command-line -parameters (e.g. it does not support setting the printer resolution). The -recognized parameters are the following: -</p> - -<blockquote> -<dl> -<dt><code>-sDEVICE=mswinpr2</code></dt> -<dd>Selects the MS Windows printer device. If Ghostscript was not -compiled with this device as the default output device, you have to specify -it on the command line.</dd> - -<dt><code>-dNoCancel</code></dt> -<dd>Hides the progress dialog, which shows the percent of the document page -already processed and also provides a <em>cancel</em> button. This option -is useful if GS is intended to print pages in the background, without any -user intervention.</dd> - -<dt><code>-sOutputFile=</code><b>"%printer%<em>printer_name</em>"</b></dt> -<dd>Specifies which printer should be used. The <em>printer_name</em> should be -typed exactly as it appears in the Printers control panel, including spaces.</dd> - -</dl> -</blockquote> - -<h3><a name="Win_options"></a>Supported options (device properties)</h3> - -<p> -Several extra options exist which cannot be set through the command-line, -but only by executing the appropriate PostScript setup code. These options -can be set through the inclusion of a setup file on the command-line: -</p> - -<blockquote><code> -gs ... setup.ps ... -</code></blockquote> - -<p> -The <code>setup.ps</code> file is responsible for the device selection, therefore -you should not specify the <code>-sDEVICE=mswinpr2</code> option on the -command-line if you are using such a setup file. Here is an example of such -a setup file: -</p> - -<blockquote><pre> -mark - /NoCancel true % don't show the cancel dialog - /BitsPerPixel 4 % force 4 bits/pixel - /UserSettings - << - /DocumentName (Ghostscript document) % name for the Windows spooler - /MaxResolution 360 % maximum document resolution - >> - (mswinpr2) finddevice % select the Windows device driver - putdeviceprops -setdevice -</pre></blockquote> - -<p> -This example disables the progress dialog (same as the <code>-dNoCancel</code> -option), forces a 4 bits/pixel output resolution and specifies additional user -settings, such as the document name (which will be displayed by the Windows -spooler for the queued document) and the maximum resolution (here 360 dpi). -It then finds and selects an instance of the MS Windows device printer -and activates it. This will show the standard printer dialog, since no -<code>/OutputFile</code> property was specified. -</p> - -<p> -The following options are available: -</p> - -<blockquote> -<dl> -<dt><code>/NoCancel <em>boolean</em></code></dt> -<dd>Disables (hides) the progress dialog when set to <em><code>true</code></em> or -show the progress dialog if not set or set to <em><code>false</code></em>.</dd> - -<dt><code>/OutputFile <em>string</em></code></dt> -<dd>Specifies which printer should be used. The string should be of the form -<code>%printer%<em>printer_name</em></code>, where the <em>printer_name</em> should be -typed exactly as it appears in the Printers control panel, including spaces.</dd> - -<dt><code>/QueryUser <em>integer</em></code></dt> -<dd>Shows the standard printer dialog (<code>1</code> or any other value), -shows the <em>printer setup dialog</em> (<code>2</code>) or selects the -<em>default Windows printer</em> without any user interaction (<code>3</code>).</dd> - -<dt><code>/BitsPerPixel <em>integer</em></code></dt> -<dd>Sets the device depth to the specified bits per pixel. Currently supported -values are <code>1</code> (monochrome), <code>4</code> (CMYK with screening -handled by Ghostscript) and <code>24</code> (True Color, dithering handled by -the Windows printer driver; this option can produce huge print jobs).</dd> - -<dt><code>/UserSettings <em>dict</em></code></dt> -<dd>Sets additional options, defined in a dictionary. The following properties can -be set:</dd> - - -<dt><code>/DocumentName <em>string</em></code></dt> -<dd>Defines the user friendly document name which will be displayed by the -Windows spooler.</dd> - -<dt><code>/DocumentRange <em>[n1 n2]</em></code></dt> -<dd>Defines the range of pages contained in the document. This information can -be used by the printer dialog, in conjunction with the following property.</dd> - -<dt><code>/SelectedRange <em>[n1 n2]</em></code></dt> -<dd>Defines the selected range of pages. This information will be displayed in -the printer dialog and will be updated after the user interaction. A PostScript -program could check these values and print only the selected page range.</dd> - -<dt><code>/MaxResolution <em>dpi</em></code></dt> -<dd>Specifies the maximum tolerated output resolution. If the selected printer has -a higher resolution than <code>dpi</code>, then Ghostscript will render the -document with a submultiple of the printer resolution. For example, if -<code>MaxResolution</code> is set to 360 and the output printer supports -up to 1200 dpi, then Ghostscript renders the document with an internal -resolution of 1200/4=300 dpi. This can be very useful to reduce the memory -requirements when printing in True Color on some high resolution ink-jet color -printers.</dd> - - -</dl> -</blockquote> - -<p> -These properties can be queried through the <code>currentpagedevice</code> -operator. The following PostScript code snippet shows how to do it for some -of the properties: -</p> - -<blockquote><pre> -currentpagedevice /BitsPerPixel get == % displays the selected depth - -currentpagedevice /UserSettings get % get the additional options.. -/us exch def % ..and assign them to a variable - -us /DocumentName get == % displays the document name -us /SelectedRange get == % displays the selected page range - -% other misc. information (don't rely on them) - -us /Color get == % 1 => monochrome output, 2 => color output -us /PrintCopies get == % displays the number of copies requested -</pre></blockquote> - -<p> -There are a few undocumented parameters stored in the <code>UserSettings</code> -dictionary. You should not rely on them. Their use is still experimental and -they could be removed in a future version. -</p> - -<h3><a name="Win_duplex"></a>Duplex printing</h3> - -<p> -If the Windows printer supports the duplex printing feature, then it will -also be available through the <code>mswinpr2</code> device. You can query -for this support through the <code>/Duplex</code> property of the -<code>currentpagedevice</code>. If it returns <code>null</code>, then -the feature is not supported by the selected printer. Otherwise, <code>true</code> -means that the printer is currently set up to print on both faces of the paper -and <code>false</code> that it is not, but that it can. -</p> - -<p> -The following example shows how to print on both faces of the paper (using -the long side of the paper as the reference): -</p> - -<blockquote><pre> -<< /Duplex true /Tumble false >> setpagedevice -</pre></blockquote> - -<hr> - -<h2><a name="SPARCprinter"></a>Sun SPARCprinter</h2> - -<p> -This section was contributed by Martin Schulte.</p> - -<p> -With a SPARCprinter you always buy software that enables you to do -PostScript printing on it. A page image is composed on the host, which -sends a bitmap to the SPARCprinter through a special SBUS video interface. -So the need for a Ghostscript interface to the SPARCPrinter seems low, but -on the other hand, Sun's software prints some PostScript drawings -incorrectly: some pages contain a thin vertical line of rubbish, and on -some Mathematica drawings the text at the axes isn't rotated. Ghostscript, -however, gives the correct results. Moreover, replacing proprietary -software should never be a bad idea.</p> - -<p> -The problem is that there has yet been no effort to make the SPARCPrinter -driver behave like a BSD output filter. I made my tests using the script -shown here.</p> - -<h3><a name="SPARC_install"></a>Installation</h3> - -<p> -Add <code>sparc.dev</code> to <code>DEVICE_DEVS</code> and compile -Ghostscript as described in the documentation on <a href="Make.htm">how to -build Ghostscript</a>. Afterwards you can use the following script as an -example for printing after modifying it with the right pathnames -- -including for <b>{GSPATH}</b> the full pathname of the Ghostscript -executable:</p> - -<blockquote> -<pre>outcmd1='/vol/local/lib/troff2/psxlate -r' -outcmd2='<b><em>{GSPATH}</em></b> -sDEVICE=sparc -sOUTPUTFILE=/dev/lpvi0 -' - -if [ $# -eq 0 ] -then - $outcmd1 | $outcmd2 -else - cat $* | $outcmd1 | $outcmd2 -fi -</pre></blockquote> - -<h3><a name="SPARC_problems"></a>Problems</h3> - -<p> -Since <code>/dev/lpi</code> can be opened only for exclusive use, if -another job has it open (engine_ctl_sparc or another Ghostscript are the -most likely candidates), Ghostscript stops with "Error: /invalidfileaccess -in --.outputpage--"</p> - -<p> -In case of common printer problems like being out of paper, a warning -describing the reason is printed to stdout. The driver tries access again -each five seconds. Due to a problem with the device driver (in the kernel) -the reason for printer failure isn't always reported correctly to the -program. This is the case, for instance, if you open the top cover (error -E5 on the printer's display). Look at the display on the printer itself if -a "Printer problem with unknown reason" is reported. Fatal errors cause -the print job to be terminated.</p> - -<p> -Note: there is some confusion whether the resolution setting should be -the integers 300 and 400, or the symbolic constants DPI300 and DPI400 -(defined in lpviio.h). Ghostscript releases have had it both ways. It -is currently the latter. However, INOUE Namihiko reports (in bug -<a href="http://bugs.ghostscript.com/show_bug.cgi?id=215256" -class="offsite">#215256</a>) -that the former works better for him. If anyone -has a definitive answer, please let us know.</p> - -<hr> - -<h2><a name="Apple"></a>Apple dot matrix printer</h2> - -<p> -This section was contributed by Mark Wedel -<<a href="mailto:master@cats.ucsc.edu">master@cats.ucsc.edu</a>>.</p> - -<p> -The Apple Dot Matrix Printer (DMP) was a parallel predecessor to the -Imagewriter printer. As far as I know, Imagewriter commands are a superset -of the Dot Matrix printer's, so the driver should generate output that can -be printed on Imagewriters.</p> - -<p> -To print images, the driver sets the printer for unidirectional printing -and 15 characters per inch (cpi), or 120dpi. It sets the line feed to 1/9 -inch. When finished, it sets the printer to bidirectional printing, -1/8-inch line feeds, and 12 cpi. There appears to be no way to reset the -printer to initial values.</p> - -<p> -This code does not set for 8-bit characters (which is required). It also -assumes that carriage return-newline is needed, and not just carriage -return. These are all switch settings on the DMP, and I have configured -them for 8-bit data and carriage return exclusively. Ensure that the Unix -printer daemon handles 8-bit (binary) data properly; in my SunOS 4.1.1 -<code>printcap</code> file the string "<code>ms=pass8,-opost</code>" -works fine for this.</p> - -<p> -Finally, you can search <code>devdemp.c</code> for -"<code>Init</code>" and "<code>Reset</code>" to find the strings that -initialize the printer and reset things when finished, and change them to -meet your needs.</p> - -<hr> - -<h2><a name="Test"></a>Special and Test devices</h2> - -<p> -The devices in this section are intended primarily for testing. They may -be interesting as code examples, as well.</p> - -<h3><a name="Bit"></a>Raw 'bit' devices</h3> - -<p>There are a collection of 'bit' devices that don't do any special formatting -but output 'raw' binary data for the page images. These are used for benchmarking -but can also be useful when you want to directly access the raster data.</p> - -<p> -The raw devices are <code>bit bitrgb bitcmyk</code>.</p> - -<h3><a name="Bounding_box_output"></a>Bounding box output</h3> - -<p> -There is a special <code>bbox</code> "device" that just prints the -bounding box of each page. You select it in the usual way:</p> - -<blockquote><code> -gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox -</code></blockquote> - -<p> -It prints the output in a format like this:</p> - -<blockquote> -<pre><code>%%BoundingBox: 14 37 570 719 -%%HiResBoundingBox: 14.3ep08066 37.547999 569.495061 718.319158 -</code></pre></blockquote> - -<p> -Currently, it always prints the bounding box on <code>stderr</code>; -eventually, it should also recognize <code>-sOutputFile=</code>.</p> - -<p> -By default, white objects don't contribute to the bounding box because -many files fill the whole page with white before drawing other objects. -This can be changed by:</p> - -<blockquote><code> -<< /WhiteIsOpaque true >> setpagedevice -</code></blockquote> - -<p> -Note that this device, like other devices, has a resolution and a (maximum) -page size. As for other devices, the product (resolution x page size) is -limited to approximately 500K pixels. By default, the resolution is 4000 -DPI and the maximum page size is approximately 125", or approximately 9000 -default (1/72") user coordinate units. If you need to measure larger pages -than this, you must reset <em>both</em> the resolution and the page size in -pixels, e.g.,</p> - -<blockquote><code> -gs -dNOPAUSE -dBATCH -sDEVICE=bbox -r100 -g500000x500000 -</code></blockquote> - -<h3><a name="Ink_coverage_output"></a>Ink coverage output</h3> - -<p> -There are two special <code>inkcov</code> devices that print the -ink coverage of each page; the inkcov device and the ink_cov device. -They are selected like this:</p> - -<blockquote><pre><code> -gs -dSAFER -dNOPAUSE -dBATCH -o- -sDEVICE=inkcov Y.pdf -gs -dSAFER -dNOPAUSE -dBATCH -o- -sDEVICE=ink_cov Y.pdf -</code></pre></blockquote> - -<p>These commands also work as expected:</p> - -<blockquote><pre><code> -gs -o X_inkcov.txt -sDEVICE=inkcov Y.pdf -gs -o X_inkcov_page%03d.txt -sDEVICE=inkcov Y.pdf -</code></pre></blockquote> - -<p> -The devices print their output in a format like this:</p> - -<blockquote> -<pre><code>Page 1 - 0.10022 0.09563 0.10071 0.06259 CMYK OK -Page 2 - 0.06108 0.05000 0.05834 0.04727 CMYK OK -</code></pre></blockquote> - -<p> -The difference between the two devices is that the inkcov device considers each rendered pixel and whether -it marks the C, M, Y or K channels. So the percentages are a measure of how many device pixels -contain that ink. The ink_cov device gives the more traditional use of ink coverage, it -also considers the amount of each colourant at each rendered pixel, so the percentages in this -case are what percentage of the ink is used on the page. -</p> -<p> -As an example, If we take a page which is covered by a pure 100% cyan fill both devices would give -the same result 1.00 0.00 0.00 0.00; each pixel is marked by the cyan ink and each pixel contains 100% cyan. -If however we use a 50% cyan fill the inkcov device will still give 1.00 0.00 0.00 0.00 as 100% of the pixels contain cyan. The -ink_cov device, however, would give a result of 0.50 0.00 0.00 0.00. -</p> - -<h3><a name="Permute"></a>Permutation (DeviceN color model)</h3> - -<p> -With no additional parameters, the device named "permute" looks -to Ghostscript like a standard CMYK contone device, and outputs a -PPM file, using a simple CMYK->RGB transform. This should be the -baseline for regression testing.</p> - -<p> -With the addition of <code>-dPermute=1</code>, the internal behavior changes -somewhat, but in most cases the resulting rendered file should be the -same. In this mode, the color model becomes "DeviceN" rather than -"DeviceCMYK", the number of components goes to six, and the color -model is considered to be the (yellow, cyan, cyan, magenta, 0, black) -tuple. This is what's rendered into the memory buffer. Finally, on -conversion to RGB for output, the colors are permuted back.</p> - -<p> -As such, this code should check that all imaging code paths are -64-bit clean. Additionally, it should find incorrect code that assumes -that the color model is one of DeviceGray, DeviceRGB, or DeviceCMYK.</p> - -<p> -Currently, the code has the limitation of 8-bit continuous tone -rendering only. An enhancement to do halftones is planned as well. Note, -however, that when testing permuted halftones for consistency, it is -important to permute the planes of the default halftone accordingly, and -that any file which sets halftones explicitly will fail a consistency -check.</p> - -<h3><a name="SPOT"></a>spotcmyk (DeviceN color model)</h3> - -<p> -The <code>spotcmyk</code> device was created for debugging and testing of the DeviceN -extensions to Ghostscript that were released in version 8.0. -There are also another device (<code>devicen</code>) in the same -source file. It were created for testing however it are not actually useful -except as example code.</p> - -<p>The <code>spotcmyk</code> device was also designed to provide example code for a -device which supports spot colors. -Spot colors need to be specified prior to opening the -first page. -This can be done via adding the -following to the command line: <code>-c "<< /SeparationColorNames [ /Name1 /Name2 ] ->> setpagedevice" -f</code>.</p> - -<p> -The <code>spotcmyk</code> device produces a binary data file (similar to the bitcmyk -device) for the CMYK data. This data file has the name specified by the "OutputFile" -parameter. -The device also produces a binary data file (similar to the bitmono device) -for each spot color plane. -These data files have the name specified by the "OutputFile" -parameter with "sn" appended to the end (where "n" is the spot color number 0 to 12)".</p> - -<p> -After the <code>spotcmyk</code> device produces the binary data files, the files are read -and PCX format versions of these files are created with ".pcx" appended to the binary -source file name.</p> - -<p> If the the <code>spotcmyk</code> is being used with three spot colors and the -"OutputFile" parameter is <code>xxx</code> then the following files would be created -by the device:</p> - -<blockquote> -<pre>xxx - binary CMYK data -xxxs0 - binary data for first spot color -xxxs1 - binary data for second spot color -xxxs2 - binary data for third spot color -xxx.pcx - CMYK data in PCX format -xxxs0.pcx - first spot color in PCX format -xxxs1.pcx - second spot color in PCX format -xxxs2.pcx - third spot color in PCX format -</pre> -</blockquote> - -<p> -The <code>spotcmyk</code> device has the creation of the binary data files separated -from the creation of the PCX files since the source file is intended as example -code and many people may not be interested in the PCX format. The PCX format was -chosen because it was simple to implement from preexisting code and viewers are -available. The PCX format does have the disadvantage that most of those viewers -are on Windows.</p> - - -<h3><a name="XCF"></a>XCF (DeviceN color model)</h3> - -<p> -The XCF file format is the native image format for the GIMP program. This format -is currently supported by two devices: <code> xcfrgb</code> and <code>xcfcmyk</code>.</p> - -<blockquote><em> -We have been warned by the people supporting the GIMP program that they reserve -the right to change the -XCF format at anytime and thus these devices may become invalid. They are being -included in the documentation because we have received some questions about -these devices do. -</em></blockquote> - -<p> -The XCF devices were created for testing of the DeviceN extensions to Ghostscript -which were released in version 8.0.</p> - -<p> -The <code>xcfrgb</code> device uses a DeviceRGB process color model and creates -a normal XCF file.</p> - -<p> -The <code>xcfcmyk</code> device was created as a means of viewing spot colors for -those users that do not have access to either Photoshop <a href="#PSD">(see the PSD -devices)</a> or a PCX viewer <a href="#SPOT">(see the <code>spotcmyk</code> -device)</a>.</p> - -<p> -The <code>xcfcmyk</code> device starts by using a DeviceCMYK process color model. The -DeviceCMYK process color model allows the <code>xcfcmyk</code> device to also -support spot colors. Spot colors need to be specified prior to opening the -first page. -This can be done via adding the -following to the command line: <code>-c "<< /SeparationColorNames [ /Name1 /Name2 ] ->> setpagedevice" -f</code>.</p> - -<p> -After a page is complete, the <code>xcfcmyk</code> converts the CMYK image data into -RGB for storing in the XCF output file. The XCF format does not currently -support CMYK data directly. The spot color planes are converted into alpha -channel planes. This is done because the XCF format does not currently support -spot colors.</p> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Drivers.htm b/doc/Drivers.htm deleted file mode 100644 index f08e0b15..00000000 --- a/doc/Drivers.htm +++ /dev/null @@ -1,3407 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>The Interface between Ghostscript and Device Drivers</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>The Interface between Ghostscript and Device Drivers</h1> - -<h2><a name="toc"></a>Table of contents</h2> - -<ul class="toc"> - <li><a href="#Adding_drivers">Adding a driver</a></li> - <li><a href="#KISS">Keeping things simple</a></li> - <li><a href="#Structure">Driver structure</a></li> - <li> - <ul> - <li><a href="#Structure_definition">Structure definition</a></li> - <li><a href="#Sophisticated">For sophisticated developers only</a></li> - </ul> - </li> - <li><a href="#coordinates_and_types">Coordinates and types</a></li> - <li> - <ul> - <li><a href="#Coordinate_system">Coordinate system</a></li> - <li><a href="#Color_definition">Color definition</a></li> - <li> - <ul> - <li><a href="#sep_and_linear_fields">Separable and linear fields</a></li> - <li><a href="#Changing_color_info_data">Changing color_info data</a></li> - </ul> - </li> - <li><a href="#Types">Types</a></li> - </ul> - </li> - <li><a href="#Coding_conventions">Coding conventions</a></li> - <li> - <ul> - <li><a href="#Allocating_storage">Allocating storage</a></li> - <li><a href="#Driver_instance_allocation">Driver instance allocation</a></li> - </ul> - </li> - <li><a href="#Printer_drivers">Printer drivers</a></li> - <li><a href="#Printer_drivers_mt">Printer drivers (Multi-threaded)</a></li> - <li><a href="#Driver_procedures">Driver procedures</a></li> - <li> - <ul> - <li><a href="#Life_cycle">Life cycle</a></li> - <li><a href="#Open_close">Open, close, sync, copy</a></li> - <li><a href="#Color_mapping">Color and alpha mapping</a></li> - <li><a href="#Pixel_level_drawing">Pixel-level drawing</a></li> - <li> - <ul> - <li><a href="#Bitmap_imaging">Bitmap imaging</a></li> - <li><a href="#Pixmap_imaging">Pixmap imaging</a></li> - <li><a href="#Compositing">Compositing</a></li> - <li> - <ul> - <li>[<a href="#S_spec">S</a>, <a href="#T_spec">T</a>, <a href="#F_spec">f</a>, - <a href="#Compositing_notes">Notes</a>]</li> - </ul> - </li> - </ul> - </li> - <li><a href="#Polygon_level_drawing">Polygon-level drawing</a></li> - <li><a href="#Linear_color_drawing">Linear color drawing</a></li> - <li><a href="#High_level_drawing">High-level drawing</a></li> - <li> - <ul> - <li><a href="#Paths">Paths</a></li> - <li><a href="#Images">Images</a> [<a href="#Images_notes">Notes</a>]</li> - <li><a href="#Text">Text</a> [<a href="#Text_notes">Notes</a>]</li> - <li><a href="#Unicode">Unicode support for high level (vector) devices</a></li> - </ul> - </li> - <li><a href="#Reading_bits_back">Reading bits back</a></li> - <li><a href="#Parameters">Parameters</a></li> - <li> - <ul> - <li><a href="#Default_CRD_parameters">Default color rendering dictionary (CRD) parameters</a></li> - </ul> - </li> - <li><a href="#External_fonts">External fonts</a></li> - <li><a href="#Page_devices">Page devices</a></li> - <li><a href="#Miscellaneous">Miscellaneous</a></li> - </ul> - </li> - <li><a href="#Tray">Tray selection</a></li> - <li> - <ul> - <li><a href="#LeadingEdge">Tray rotation and the LeadingEdge parameter</a></li> - <li><a href="#LeadingPage">Interaction between LeadingEdge and PageSize</a></li> - </ul> - </li> -</ul> - -<!-- [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 on <a href="Make.htm">how to build -Ghostscript</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Adding_drivers"></a>Adding a driver</h2> - -<p> -To add a driver to Ghostscript, first pick a name for your device, say -"<code>smurf</code>". (Device names must be 1 to 8 characters, begin -with a letter, and consist only of letters, digits, and underscores. Case -is significant: all current device names are lower case.) Then all you -need do is edit <code>contrib.mak</code> in two places.</p> - -<ol> -<li>The list of devices, in the section headed "Catalog". Add -<code>smurf</code> to the list.</li> - -<li>The section headed "Device drivers". - -<p> -Suppose the files containing the smurf driver are called -"<code>joe</code>" and "<code>fred</code>". Then you should add the -following lines:</p> - -<blockquote> -<pre># ------ The SMURF device ------ # - -smurf_=$(GLOBJ)joe.$(OBJ) $(GLOBJ)fred.$(OBJ) -$(DD)smurf.dev: $(smurf_) - $(SETDEV) $(DD)smurf $(smurf_) - -$(GLOBJ)joe.$(OBJ) : $(GLSRC)joe.c - $(GLCC) $(GLO_)joe.$(OBJ) $(C_) $(GLSRC)joe.c - -$(GLOBJ)fred.$(OBJ) : $(GLSRC)fred.c - $(GLCC) $(GLO_)fred.$(OBJ) $(C_) $(GLSRC)fred.c</pre> -</blockquote> - -<p> -and whatever <code>joe.c</code> and <code>fred.c</code> depend on. -If the smurf driver also needs special libraries, for instance a library -named "<code>gorf</code>", then the entry should look like this:</p> - -<blockquote> -<pre>$(DD)smurf.dev : $(smurf_) - $(SETDEV) $(DD)smurf $(smurf_) - $(ADDMOD) $(DD)smurf -lib gorf</pre> -</blockquote> - -<p> -If, as will usually be the case, your driver is a printer driver (as -<a href="#Printer_drivers">discussed below</a>), the device entry should -look like this:</p> - -<blockquote> -<pre>$(DD)smurf.dev : $(smurf_) $(GLD)page.dev - $(SETPDEV) $(DD)smurf $(smurf_)</pre> -</blockquote> - -<p> -or</p> - -<blockquote> -<pre>$(DD)smurf.dev : $(smurf_) $(GLD)page.dev - $(SETPDEV) $(DD)smurf $(smurf_) - $(ADDMOD) $(DD)smurf -lib gorf</pre> -</blockquote> - -<p> -Note that the space before the :, and the explicit compilation rules for the -.c files, are required for portability,</p> -</li> -</ol> - -<hr> - -<h2><a name="KISS"></a>Keeping things simple</h2> - -<p> -If you want to add a simple device (specifically, a monochrome printer), you -probably don't need to read the rest of this document; just use the code in -an existing driver as a guide. The Epson and Canon BubbleJet drivers <a -href="../devices/gdevepsn.c">gdevepsn.c</a> and <a -href="../devices/gdevbj10.c">gdevbj10.c</a> are good models for dot-matrix -printers, which require presenting the data for many scan lines at once; the -DeskJet/LaserJet drivers in <a href="../devices/gdevdjet.c">gdevdjet.c</a> are -good models for laser printers, which take a single scan line at a time but -support data compression. For color printers, there are unfortunately no -good models: the two major color inkjet printer drivers, <a -href="../devices/gdevcdj.c">gdevcdj.c</a> and <a -href="../devices/gdevstc.c">gdevstc.c</a>, are far too complex to read.</p> - -<p> -On the other hand, if you're writing a driver for some more esoteric -device, you probably do need at least some of the information in the rest -of this document. It might be a good idea for you to read it in -conjunction with one of the existing drivers.</p> - -<p> -Duplication of code, and sheer volume of code, is a serious maintenance and -distribution problem for Ghostscript. If your device is similar to an -existing one, try to implement your driver by adding some parameterization -to an existing driver rather than by copying code to create an entirely new -source module. <a href="../devices/gdevepsn.c">gdevepsn.c</a> and <a -href="../devices/gdevdjet.c">gdevdjet.c</a> are good examples of this approach.</p> - -<hr> - -<h2><a name="Structure"></a>Driver structure</h2> - -<p> -A device is represented by a structure divided into three parts:</p> - -<ul> -<li>parameters that are present in all devices but may be different for -each device or instance;</li> - -<li>an initialize_device_procs procedure; and</li> - -<li>device-specific parameters that may be different for each instance.</li> -</ul> - -<p> -A prototype of the parameter structure (including both generic and -device-specific parameters) is defined and initialized at compile time, but -is copied and filled in when an instance of the device is created. This -structure should be declared as <code>const</code>, but for backward -compatibility reasons it is not.</p> - -<p> -The <code>gx_device_common</code> macro defines the common structure -elements, with the intent that devices define and export a structure along -the following lines. Do not fill in the individual generic parameter values -in the usual way for C structures: use the macros defined for this purpose -in <a href="../base/gxdevice.h">gxdevice.h</a> or, if applicable, <a -href="../base/gdevprn.h">gdevprn.h</a>.</p> - -<blockquote> -<pre>typedef struct smurf_device_s { - gx_device_common; - <b><em>... device-specific parameters ...</em></b> -} smurf_device; -smurf_device gs_smurf_device = { - <b><em>... macro for generic parameter values ...,</em></b> - <b><em>initialize_device_procs,</em></b> - <b><em>... device-specific parameter values if any ...</em></b> -};</pre> -</blockquote> -<p> -The device structure instance <b>must</b> have the name -<code>gs_smurf_device</code>, where <code>smurf</code> is the device -name used in <code>contrib.mak</code>. <code>gx_device_common</code> -is a macro consisting only of the element definitions. </p> -<p> -The <code>initialize_device_procs</code> function pointer is called when -the device is created. Its sole job is to initialize the entries in -the device procedure table. On entry, the device procedure table will -be full of NULL pointers. On exit, any NULLs left in the table will be -filled in with pointers to the default routines. Therefore, the routine -should set any non-default entries itself. -<p> -Devices that are (in object-oriented terms) derived from 'base' classes -(for instance a new printer device that derives from the <code>prn</code> -device) can call provided helper functions for setting the standard -functions for that base class. -<p> -For example, if the smurf device was a printer device, its -<code>initialize_device_procs</code> procedure might look like:</p> -<blockquote> -<pre>static void smurf_initialize_device_procs(gx_device *dev) { - /* We are derived from a prn device, and can print in the background */ - gdev_prn_initialize_bg(dev); - - /* Override functions for our specifics */ - set_dev_proc(dev, map_color_rgb, smurf_map_color_rgb); - set_dev_proc(dev, map_rgb_color, smurf_map_rgb_color); - ... -}</pre> -</blockquote> -<p> -The initialize procedure function pointer does not live in the in the -device procedure table (and as such is statically initialized at compile -time). Nonetheless, we refer to this as being a device procedure in the -rest of the discussion here. -<p> -Note that the <code>initialize_device_procs</code> function may be called -with a pointer to a <code>gx_device</code> rather than to the derived -device class. This happens frequently when one device wants to obtain -the prototype of another to copy device procedures around. Initialization -of items in the device other than device procs should therefore be -reserved for the <code>initialize_device</code> device procedure. -<p> -The use of the initialize procedure is new to Ghostscript 9.55. Previous -versions used a statically initialized table of device procedures. We -changed to a dynamically initialized system to more easily cope with -future changes to the device procedures. -<p> -All the device procedures are called with the device as the first argument. -Since each device type is actually a different structure type, the device -procedures must be declared as taking a <code>gx_device *</code> as -their first argument, and must cast it to -<code>smurf_device *</code> internally. For example, in the code -for the "memory" device, the first argument to all routines is called -<code>dev</code>, but the routines actually use <code>mdev</code> to -refer to elements of the full structure, using the following standard -initialization statement at the beginning of each procedure:</p> - -<blockquote> -<pre>gx_memory_device *const mdev = (gx_device_memory *)dev;</pre> -</blockquote> - -<p> -(This is a cheap version of "object-oriented" programming: in C++, for -example, the cast would be unnecessary, and in fact the procedure table -would be constructed by the compiler.)</p> - -<h3><a name="Structure_definition"></a>Structure definition</h3> - -<p> -You should consult the definition of struct <code>gx_device_s</code> in -<a href="../base/gxdevice.h">gxdevice.h</a> for the complete details of the -generic device structure. Some of the most important members of this -structure for ordinary drivers are:</p> - -<blockquote><table> - <tr valign="top"> <td><code>const char *dname;</code></td> - - <td>The device name</td></tr> - - <tr valign="top"> <td><code>bool is_open;</code></td> - - <td>True if device has been opened</td></tr> -<tr valign="top"> <td><code>gx_device_color_info color_info;</code></td> - - <td>Color information</td></tr> -<tr valign="top"> <td><code>int width;</code></td> - - <td>Width in pixels</td></tr> -<tr valign="top"> <td><code>int height;</code></td> - - <td>Height in pixels</td></tr> -</table></blockquote> - -<p> -The name in the structure (<code>dname</code>) should be the same as the -name in <a href="../devices/contrib.mak">contrib.mak</a>.</p> - -<h3><a name="Sophisticated"></a>For sophisticated developers only</h3> - -<p> -If for any reason you need to change the definition of the basic device -structure, or to add procedures, you must change the following places:</p> - -<blockquote><ul> -<li>This document and the <a href="News.htm">news document</a> (if you want - to keep the documentation up to date).</li> -<li>The definition of <code>gx_device_common</code> and the procedures - in <a href="../base/gxdevcli.h">gxdevcli.h</a>.</li> -<li>Possibly, the default forwarding procedures declared in - <a href="../base/gxdevice.h">gxdevice.h</a> and implemented in - <a href="../base/gdevnfwd.c">gdevnfwd.c</a>.</li> -<li>The device procedure record completion routines in - <a href="../base/gdevdflt.c">gdevdflt.c</a>.</li> -<li>Possibly, the default device implementation in - <a href="../base/gdevdflt.c">gdevdflt.c</a>, - <a href="../base/gdevddrw.c">gdevddrw.c</a>, and - <a href="../base/gxcmap.c">gxcmap.c</a>.</li> -<li>The bounding box device in <a href="../base/gdevbbox.c">gdevbbox.c</a> - (probably just adding <code>NULL</code> procedure entries if the - new procedures don't produce output).</li> -<li>These devices that must have complete (non-defaulted) procedure vectors:</li> -<li> -<ul> -<li>The null device in <a href="../base/gdevnfwd.c">gdevnfwd.c</a>.</li> -<li>The command list "device" in <a href="../base/gxclist.c">gxclist.c</a>. - This is not an actual device; it only defines procedures.</li> -<li>The "memory" devices in <a href="../base/gdevmem.h">gdevmem.h</a> and - <code>gdevm*.c</code>.</li> -</ul> -</li> -<li>The clip list accumulation "device" in - <a href="../base/gxacpath.c">gxacpath.c</a>.</li> -<li>The clipping "devices" <a href="../base/gxclip.c">gxclip.c</a>, - <a href="../base/gxclip2.c">gxclip2.c</a>, - and <a href="../base/gxclipm.c">gxclipm.c</a>.</li> -<li>The pattern accumulation "device" in - <a href="../base/gxpcmap.c">gxpcmap.c</a>.</li> -<li>The hit detection "device" in <a href="../base/gdevhit.c">gdevhit.c</a>.</li> -<li>The generic printer device macros in - <a href="../base/gdevprn.h">gdevprn.h</a>.</li> -<li>The generic printer device code in - <a href="../base/gdevprn.c">gdevprn.c</a>.</li> -<li>The RasterOp source device in - <a href="../base/gdevrops.c">gdevrops.c</a>.</li> -</ul></blockquote> - -<p> -You may also have to change the code for -<code>gx_default_get_params</code> or -<code>gx_default_put_params</code> in <a -href="../base/gsdparam.c">gsdparam.c</a>.</p> - -<p> -You should not have to change any of the real devices in the standard -Ghostscript distribution (listed in <a href="../base/devs.mak">devs.mak</a> -and <a href="../devices/contrib.mak">contrib.mak</a>) or any of your own -devices, because all of them are supposed to use the macros in <a -href="../base/gxdevice.h">gxdevice.h</a> or <a -href="../base/gdevprn.h">gdevprn.h</a> to define and initialize their state.</p> - -<hr> - -<h2><a name="coordinates_and_types"></a>Coordinates and types</h2> - -<h3><a name="Coordinate_system"></a>Coordinate system</h3> - -<p> -Since each driver specifies the initial transformation from user -coordinates to device coordinates, the driver can use any coordinate system -it wants, as long as a device coordinate will fit in an -<code>int</code>. (This is only an issue on DOS systems, where ints are -only 16 bits. User coordinates are represented as floats.) Most current -drivers use a coordinate system with (0,0) in the upper left corner, with -<b><em>X</em></b> increasing to the right and <b><em>Y</em></b> increasing -toward the bottom. However, there is supposed to be nothing in the rest of -Ghostscript that assumes this, and indeed some drivers use a coordinate -system with (0,0) in the lower left corner.</p> - -<p> -Drivers must check (and, if necessary, clip) the coordinate parameters given -to them: they should not assume the coordinates will be in bounds. The -<code>fit_fill</code> and <code>fit_copy</code> macros in <a -href="../base/gxdevice.h">gxdevice.h</a> are very helpful in doing this.</p> - -<h3><a name="Color_definition"></a>Color definition</h3> - -<p> -Between the Ghostscript graphics library and the device, colors are -represented in three forms. Color components in a color space (Gray, RGB, -DeviceN, etc.) represented as <code>frac</code> values. Device colorants -are represented as <code>gx_color_value</code> values. For many -procedures, colors are represented in a type called -<code>gx_color_index</code>. -All three types are described in more detail in <a href="#Types">Types</a></p> - -<p> -The <code>color_info</code> member of the device structure defines the -color and gray-scale capabilities of the device. Its type is defined as -follows:</p> - -<blockquote> -<pre> -/* - * The enlarged color model information structure: Some of the - * information that was implicit in the component number in - * the earlier conventions (component names, polarity, mapping - * functions) are now explicitly provided. - * - * Also included is some information regarding the encoding of - * color information into gx_color_index. Some of this information - * was previously gathered indirectly from the mapping - * functions in the existing code, specifically to speed up the - * halftoned color rendering operator (see - * gx_dc_ht_colored_fill_rectangle in gxcht.c). The information - * is now provided explicitly because such optimizations are - * more critical when the number of color components is large. - * - * Note: no pointers have been added to this structure, so there - * is no requirement for a structure descriptor. - */ -typedef struct gx_device_color_info_s { - - /* - * max_components is the maximum number of components for all - * color models supported by this device. This does not include - * any alpha components. - */ - int max_components; - - /* - * The number of color components. This does not include any - * alpha-channel information, which may be integrated into - * the gx_color_index but is otherwise passed as a separate - * component. - */ - int num_components; - - /* - * Polarity of the components of the color space, either - * additive or subtractive. This is used to interpret transfer - * functions and halftone threshold arrays. Possible values - * are GX_CM_POLARITY_ADDITIVE or GX_CM_POLARITY_SUBTRACTIVE - */ - gx_color_polarity_t polarity; - - /* - * The number of bits of gx_color_index actually used. - * This must be <= sizeof(gx_color_index), which is usually 64. - */ - byte depth; - - /* - * Index of the gray color component, if any. The max_gray and - * dither_gray values apply to this component only; all other - * components use the max_color and dither_color values. - * - * This will be GX_CINFO_COMP_NO_INDEX if there is no gray - * component. - */ - byte gray_index; - - /* - * max_gray and max_color are the number of distinct native - * intensity levels, less 1, for the gray and all other color - * components, respectively. For nearly all current devices - * that support both gray and non-gray components, the two - * parameters have the same value. - * - * dither_grays and dither_colors are the number of intensity - * levels between which halftoning can occur, for the gray and - * all other color components, respectively. This is - * essentially redundant information: in all reasonable cases, - * dither_grays = max_gray + 1 and dither_colors = max_color + 1. - * These parameters are, however, extensively used in the - * current code, and thus have been retained. - * - * Note that the non-gray values may now be relevant even if - * num_components == 1. This simplifies the handling of devices - * with configurable color models which may be set for a single - * non-gray color model. - */ - gx_color_value max_gray; /* # of distinct color levels -1 */ - gx_color_value max_color; - - gx_color_value dither_grays; - gx_color_value dither_colors; - - /* - * Information to control super-sampling of objects to support - * anti-aliasing. - */ - gx_device_anti_alias_info anti_alias; - - /* - * Flag to indicate if gx_color_index for this device may be divided - * into individual fields for each component. This is almost always - * the case for printers, and is the case for most modern displays - * as well. When this is the case, halftoning may be performed - * separately for each component, which greatly simplifies processing - * when the number of color components is large. - * - * If the gx_color_index is separable in this manner, the comp_shift - * array provides the location of the low-order bit for each - * component. This may be filled in by the client, but need not be. - * If it is not provided, it will be calculated based on the values - * in the max_gray and max_color fields as follows: - * - * comp_shift[num_components - 1] = 0, - * comp_shift[i] = comp_shift[i + 1] - * + ( i == gray_index ? ceil(log2(max_gray + 1)) - * : ceil(log2(max_color + 1)) ) - * - * The comp_mask and comp_bits fields should be left empty by the client. - * They will be filled in during initialization using the following - * mechanism: - * - * comp_bits[i] = ( i == gray_index ? ceil(log2(max_gray + 1)) - * : ceil(log2(max_color + 1)) ) - * - * comp_mask[i] = (((gx_color_index)1 << comp_bits[i]) - 1) - * << comp_shift[i] - * - * (For current devices, it is almost always the case that - * max_gray == max_color, if the color model contains both gray and - * non-gray components.) - * - * If separable_and_linear is not set, the data in the other fields - * is unpredictable and should be ignored. - */ - gx_color_enc_sep_lin_t separable_and_linear; - byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS]; - byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index comp_mask[GX_DEVICE_COLOR_MAX_COMPONENTS]; - /* - * Pointer to name for the process color model. - */ - const char * cm_name; - -} gx_device_color_info; -</pre> -</blockquote> - -<p> -Note: See <a href="#Changing_color_info_data">Changing color_info data</a> before changing -any information in the <code>color_info structure</code> for a device. </p> - -<p> -It is recommended that the values for this structure be defined using one -of the standard macros provided for this purpose. This allows for future -changes to be made to the structure without changes being required in the -actual device code.</p> - -<p> -The following macros (in <a href="../base/gxdevcli.h">gxdevcli.h</a>) provide -convenient shorthands for initializing this structure for ordinary -black-and-white or color devices:</p> - -<blockquote> -<code>#define dci_black_and_white</code> ...<br> -<code>#define dci_color(depth,maxv,dither)</code> ... -</blockquote> - -<p> -The <code>#define dci_black_and_white</code> macro defines a -single bit monochrome device (For example: a typical monochrome printer device.)</p> - -<p> -The <code>#define dci_color(depth,maxv,dither)</code> macro can be used -to define a 24 bit RGB device or a 4 or 32 bit CMYK device.</p> - -<p> -The <code>#define dci_extended_alpha_values</code> macro (in -<a href="../base/gxdevcli.h">gxdevcli.h</a>) -specifies most of the current fields in the structure. However this macro allows -only the default setting for the comp_shift, comp_bits, and comp_mask fields -to be set. Any device which requires a non-default setting for these fields -has to correctly these fields during the device open procedure. -See -<a href="#sep_and_linear_fields">Separable and linear fields></a> and -<a href="#Changing_color_info_data">Changing color_info data</a>.</p> - -<p> -The idea is that a device has a certain number of gray levels -(<code>max_gray</code>+1) and a certain number of colors -(<code>max_rgb</code>+1) that it can produce directly. When Ghostscript -wants to render a given color space color value as a device color, it first tests -whether the color is a gray level and if so:</p> - -<blockquote> -If <code>max_gray</code> is large (>= 31), Ghostscript asks the -device to approximate the gray level directly. If the device returns a -valid <code>gx_color_index</code>, Ghostscript uses it. Otherwise, -Ghostscript assumes that the device can represent -<code>dither_gray</code> distinct gray levels, equally spaced along the -diagonal of the color cube, and uses the two nearest ones to the desired -color for halftoning. -</blockquote> - -<p> -If the color is not a gray level:</p> - -<blockquote> -If <code>max_rgb</code> is large (>= 31), Ghostscript asks the device -to approximate the color directly. If the device returns a valid -<code>gx_color_index</code>, Ghostscript uses it. Otherwise, - Ghostscript assumes that the device can represent</blockquote> - -<blockquote> -<code>dither_rgb</code> × <code>dither_rgb</code> × <code>dither_rgb</code> -</blockquote> - -<p> -distinct colors, equally spaced throughout the color cube, and uses two of -the nearest ones to the desired color for halftoning.</p> - -<h4><a name="sep_and_linear_fields"></a>Separable and linear fields</h4> -<p> -The three fields <code>comp_shift</code>, <code>comp_bits</code>, and -<code>comp_mask</code> are only used if the <code>separable_and_linear</code> -field is set to <code>GX_CINFO_SEP_LIN</code>. In this situation a <code>gx_color_index</code> -value must represent a combination created by or'ing bits for each of the devices's -output colorants. The <code>comp_shift</code> array defines the location -(shift count) of each colorants bits in the output gx_color_index value. The -<code>comp_bits</code> array defines the number of bits for each colorant. -The <code>comp_mask</code> array contains a mask which can be used to isolate -the bits for each colorant. These fields must be set if the device supports -more than four colorants.</p> - -<h4><a name="Changing_color_info_data"></a>Changing color_info data</h4> - -<p> For most devices, the information in the device's <code>color_info</code> -structure is defined by the various device definition macros and the data remains -constant during the entire existence of the device. In general the Ghostscript -graphics assumes that the information is constant. However some devices want -to modify the data in this structure.</p> - -<p> -The device's <code>put_params</code> procedure may change -<code>color_info</code> field values. -After the data has been modified then the -device should be closed (via a call to <code>gs_closedevice</code>). Closing -the device will erase the current page so these changes should only be made -before anything has been drawn on a page.</p> - -<p> The device's <code>open_device</code> procedure may change -<code>color_info</code> field values. These changes should be done before -any other procedures are called.</p> - -<p> -The Ghostscript graphics library -uses some of the data in <code>color_info</code> to set the default -procedures for the -<code>get_color_mapping_procs</code>, -<code>get_color_comp_index</code>, -<code>encode_color</code>, and -<code>decode_color</code> procedures. -These default procedures are set when the -device is originally created. If any changes are made to the -<code>color_info</code> fields then the device's <code>open_device</code> -procedure -has responsibility for insuring that the correct procedures are contained -in the device structure. (For an example, see the display device open procedure -<code>display_open</code> and its subroutine -<code>display_set_color_format</code> -(in <a href="../devices/gdevdsp.c">gdevdsp.c</a>).</p> - - -<h3><a name="Types"></a>Types</h3> - -<p> -Here is a brief explanation of the various types that appear as parameters -or results of the drivers.</p> - -<dl> -<dt><code>frac</code> (defined in <a href="../base/gxfrac.h">gxfrac.h</a>)</dt> -<dd>This is the type used to represent color values for the input to the -color model mapping procedures. It is currently defined as a short. It has a -range of <code>frac_0</code> to <code>frac_1</code>.</dd> -</dl> - -<dl> -<dt><code>gx_color_value</code> (defined in -<a href="../base/gxdevice.h">gxdevice.h</a>)</dt> -<dd>This is the type used to represent RGB or CMYK color values. It is -currently equivalent to unsigned short. However, Ghostscript may use less -than the full range of the type to represent color values: -<code>gx_color_value_bits</code> is the number of bits actually used, -and <code>gx_max_color_value</code> is the maximum value, equal to -(2^<small><sup><code>gx_max_color_value_bits</code></sup></small>)-1.</dd> -</dl> - -<dl> -<dt><code>gx_device</code> (defined in -<a href="../base/gxdevice.h">gxdevice.h</a>)</dt> -<dd>This is the device structure, as explained above.</dd> -</dl> - -<dl> -<dt><code>gs_matrix</code> (defined in -<a href="../base/gsmatrix.h">gsmatrix.h</a>)</dt> -<dd>This is a 2-D homogeneous coordinate transformation matrix, used by -many Ghostscript operators.</dd> -</dl> - -<dl> -<dt><code>gx_color_index</code> (defined in -<a href="../base/gxcindex.h">gxcindex.h</a>)</dt> -<dd>This is meant to be whatever the driver uses to represent a device -color. For example, it might be an index in a color map, or it might be R, -G, and B values packed into a single integer. The Ghostscript graphics library -gets <code>gx_color_index</code> values from the device's -<code>encode_color</code> and hands them back as arguments to several other -procedures. If the <code>separable_and_linear</code> field in the device's -<code>color_info</code> structure is not set to -<code>GX_CINFO_SEP_LIN</code> then Ghostscript does not do -any computations with <code>gx_color_index</code> values. - -<p> -The special -value <code>gx_no_color_index</code> (defined as -<code>(~(gx_color_index)(0))</code> ) means "transparent" for some of -the procedures.</p> - -<p> -The size of <code>gx_color_index</code> can be either 32 or 64 bits. The -choice depends upon the architecture of the CPU and the compiler. The default -type definition is simply: </p> - -<blockquote><code> -typedef unsigned long gx_color_index; -</code></blockquote> - -<p>However if <code>GX_COLOR_INDEX_TYPE</code> is defined, then it is used -as the type for <code>gx_color_index</code>.</p> - -<blockquote><code> -typedef GX_COLOR_INDEX_TYPE gx_color_index; -</code></blockquote> - -<p>The smaller size (32 bits) may produce more efficient or faster executing -code. The larger size (64 bits) is needed for representing either more -bits per component or more components. An example of the later case is -a device that supports 8 bit contone colorants using a DeviceCMYK process -color model with its four colorants and also supports additional spot -colorants.</p> - -<p> -Currently autoconf attempts to find a 64 bit type definition for the -compiler being used, and if a 64 bit type is found then -<code>GX_COLOR_INDEX_TYPE</code> is set to the type.</p> - -<p> -For Microsoft and the MSVC compiler, <code>GX_COLOR_INDEX_TYPE</code> will -be set to <code>unsigned _int64</code> if <code>USE_LARGE_COLOR_INDEX</code> -is set to 1 either on the make command line or by editing the definition - in <a href="../psi/msvc32.mak">msvc32.mak</a> </p> - - </dd> - -</dl> - -<dl> -<dt><code>gs_param_list</code> (defined in <a -href="../base/gsparam.h">gsparam.h</a>) </dt> - <dd>This is a parameter list, which is used to read and set attributes in a -device. See the comments in <a href="../base/gsparam.h">gsparam.h</a>, and -the <a href="#Parameters">description of the <code>get_params</code> and -<code>put_params</code> procedures</a> below, for more detail.</dd> -</dl> - -<dl> -<dt><code>gx_tile_bitmap</code> (defined in -<a href="../base/gxbitmap.h">gxbitmap.h</a>) -<br><code>gx_strip_bitmap</code> (defined in -<a href="../base/gxbitmap.h">gxbitmap.h</a>)</dt> -<dd>These structure types represent bitmaps to be used as a tile for -filling a region (rectangle). <code>gx_tile_bitmap</code> is an -older, deprecated type lacking <code>shift</code> and -<code>rep_shift</code>; -<code>gx_strip_bitmap</code> has superseded it, and should be -used in new code. Here is a copy of the relevant part of the file: - -<blockquote> -<pre> -/* - * Structure for describing stored bitmaps. - * Bitmaps are stored bit-big-endian (i.e., the 2^7 bit of the first - * byte corresponds to x=0), as a sequence of bytes (i.e., you can't - * do word-oriented operations on them if you're on a little-endian - * platform like the Intel 80x86 or VAX). Each scan line must start on - * a (32-bit) word boundary, and hence is padded to a word boundary, - * although this should rarely be of concern, since the raster and width - * are specified individually. The first scan line corresponds to y=0 - * in whatever coordinate system is relevant. - * - * For bitmaps used as halftone tiles, we may replicate the tile in - * X and/or Y, but it is still valuable to know the true tile dimensions - * (i.e., the dimensions prior to replication). Requirements: - * width % rep_width = 0 - * height % rep_height = 0 - * - * For halftones at arbitrary angles, we provide for storing the halftone - * data as a strip that must be shifted in X for different values of Y. - * For an ordinary (non-shifted) halftone that has a repetition width of - * W and a repetition height of H, the pixel at coordinate (X,Y) - * corresponds to halftone pixel (X mod W, Y mod H), ignoring phase; - * for a shifted halftone with shift S, the pixel at (X,Y) corresponds - * to halftone pixel ((X + S * floor(Y/H)) mod W, Y mod H). In other words, - * each Y increment of H shifts the strip left by S pixels. - * - * As for non-shifted tiles, a strip bitmap may include multiple copies - * in X or Y to reduce loop overhead. In this case, we must distinguish: - * - The height of an individual strip, which is the same as - * the height of the bitmap being replicated (rep_height, H); - * - The height of the entire bitmap (size.y). - * Similarly, we must distinguish: - * - The shift per strip (rep_shift, S); - * - The shift for the entire bitmap (shift). - * Note that shift = (rep_shift * size.y / rep_height) mod rep_width, - * so the shift member of the structure is only an accelerator. It is, - * however, an important one, since it indicates whether the overall - * bitmap requires shifting or not. - * - * Note that for shifted tiles, size.y is the size of the stored bitmap - * (1 or more strips), and NOT the height of the actual tile. The latter - * is not stored in the structure at all: it can be computed as H * W / - * gcd(S, W). - * - * If the bitmap consists of a multiple of W / gcd(S, W) copies in Y, the - * effective shift is zero, reducing it to a tile. For simplicity, we - * require that if shift is non-zero, the bitmap height be less than H * W / - * gcd(S, W). I.e., we don't allow strip bitmaps that are large enough to - * include a complete tile but that don't include an integral number of - * tiles. Requirements: - * rep_shift < rep_width - * shift = (rep_shift * (size.y / rep_height)) % rep_width - * - * For the benefit of the planar device, we now have a num_planes field. - * For chunky data this should be set to 1. For planar data, the data pointer - * points to the first plane of data; subsequent planes of data follow - * immediately after this as if there were num_planes * height lines of data. - */ -typedef struct gx_strip_bitmap_s { - byte *data; - int raster; /* bytes per scan line */ - gs_int_point size; /* width, height */ - gx_bitmap_id id; - ushort rep_width, rep_height; /* true size of tile */ - ushort rep_shift; - ushort shift; - int num_planes; -} gx_strip_bitmap;</pre> -</blockquote> - -</dd> - -</dl> - -<hr> - -<h2><a name="Coding_conventions"></a>Coding conventions</h2> - -<p> -All the driver procedures defined below that return <code>int</code> -results return 0 on success, or an appropriate negative error code in the -case of error conditions. The error codes are defined in <a -href="../base/gserrors.h">gserrors.h</a>; they correspond directly to the -errors defined in the PostScript language reference manuals. The most -common ones for drivers are:</p> - -<blockquote><dl> -<dt><code>gs_error_invalidfileaccess</code> </dt> -<dd>An attempt to open a file failed.</dd> - -<dt><code>gs_error_ioerror</code> </dt> -<dd>An error occurred in reading or writing a file.</dd> - -<dt><code>gs_error_limitcheck</code> </dt> -<dd>An otherwise valid parameter value was too large for the -implementation.</dd> - -<dt><code>gs_error_rangecheck</code> </dt> -<dd>A parameter was outside the valid range.</dd> - -<dt><code>gs_error_VMerror</code> </dt> -<dd>An attempt to allocate memory failed. (If this happens, the procedure -should release all memory it allocated before it returns.)</dd> -</dl></blockquote> - -<p> -If a driver does return an error, rather than a simple return statement it -should use the <code>return_error</code> macro defined in <a -href="../base/gx.h">gx.h</a>, which is automatically included by <a -href="../base/gdevprn.h">gdevprn.h</a> but not by <a -href="../base/gserrors.h">gserrors.h</a>. For example</p> - -<blockquote> -<code> return_error(gs_error_VMerror); -</code></blockquote> - -<h3><a name="Allocating_storage"></a>Allocating storage</h3> - -<p> -While most drivers (especially printer drivers) follow a very similar -template, there is one important coding convention that is not obvious from -reading the code for existing drivers: driver procedures must not use -<code>malloc</code> to allocate any storage that stays around after the -procedure returns. Instead, they must use <code>gs_malloc</code> and -<code>gs_free</code>, which have slightly different calling conventions. -(The prototypes for these are in <a href="../base/gsmemory.h">gsmemory.h</a>, -which is included in <a href="../base/gx.h">gx.h</a>, which is included in <a -href="../base/gdevprn.h">gdevprn.h</a>.) This is necessary so that -Ghostscript can clean up all allocated memory before exiting, which is -essential in environments that provide only single-address-space -multi-tasking (some versions of Microsoft Windows). </p> - -<blockquote> -<pre>char *gs_malloc(uint num_elements, uint element_size, - const char *client_name);</pre> -</blockquote> - -<p> -Like <code>calloc</code>, but unlike <code>malloc</code>, -<code>gs_malloc</code> takes an element count and an element size. For -structures, <code>num_elements</code> is 1 andi -<code>element_size</code> is <code>sizeof</code> the structure; for -byte arrays, <code>num_elements</code> is the number of bytes and -<code>element_size</code> is 1. Unlike <code>calloc</code>, -<code>gs_malloc</code> does <b>not</b> clear the block of storage. </p> - -<p> -The <code>client_name</code> is used for tracing and debugging. It must -be a real string, not <code>NULL</code>. Normally it is the name of the -procedure in which the call occurs.</p> - -<blockquote> -<pre>void gs_free(char *data, uint num_elements, uint element_size, - const char *client_name);</pre> -</blockquote> - -<p> -Unlike <code>free</code>, <code>gs_free</code> demands that -<code>num_elements</code> and element_size be supplied. It also -requires a client name, like <code>gs_malloc</code>. </p> - -<h3><a name="Driver_instance_allocation"></a>Driver instance allocation</h3> - -<p> -All driver instances allocated by Ghostscript's standard allocator must -point to a "structure descriptor" that tells the garbage collector how to -trace pointers in the structure. For drivers registered in the normal way -(using the makefile approach described above), no special care is needed as -long as instances are created only by calling the -<code>gs_copydevice</code> procedure defined in <a -href="../base/gsdevice.h">gsdevice.h</a>. If you have a need to define -devices that are not registered in this way, you must fill in the stype -member in any dynamically allocated instances with a pointer to the same -structure descriptor used to allocate the instance. For more information -about structure descriptors, see <a href="../base/gsmemory.h">gsmemory.h</a> -and <a href="../base/gsstruct.h">gsstruct.h</a>. </p> - -<hr> - -<h2><a name="Printer_drivers"></a>Printer drivers</h2> - -<p> -Printer drivers (which include drivers that write some kind of raster file) -are especially simple to implement. -The printer driver must implement a <code>print_page</code> or -<code>print_page_copies</code> procedure. There are macros in <a -href="../base/gdevprn.h">gdevprn.h</a> that generate the device structure for -such devices, of which the simplest is <code>prn_device</code>; for an -example, see <a href="../devices/gdevbj10.c">gdevbj10.c</a>. If you are writing -a printer driver, we suggest you start by reading <a -href="../base/gdevprn.h">gdevprn.h</a> and the <a -href="#Color_mapping">subsection on "Color mapping"</a> below; you may be -able to ignore all the rest of the driver procedures.</p> - -<p> -The <code>print_page</code> procedures are defined as follows:</p> - -<blockquote> -<pre>int (*print_page)(gx_device_printer *, FILE *) -int (*print_page_copies)(gx_device_printer *, FILE *, int)</pre> -</blockquote> - -<p> -This procedure must read out the rendered image from the device and write -whatever is appropriate to the file. To read back one or more scan lines -of the image, the <code>print_page</code> procedure must call one of -several procedures. Traditionally devices have called -<tt>gdev_prn_copy_scan_lines</tt>, <tt>gdev_prn_get_bits</tt>, or -the generic <tt>get_bits_rectangle</tt> device entry point. Alternatively -devices may now call the new <tt>process_page</tt> entrypoint, which can -have significant performance advantages in <a href="#Printer_drivers_mt">multi-threaded</a> situations.</p> - -<blockquote> -<pre>int gdev_prn_copy_scan_lines(gx_device_printer *pdev, int y, byte *str, - uint size)</pre> -</blockquote> - -<p> -For this procedure, <code>str</code> is where the data should be copied to, and <code>size</code> is -the size of the buffer starting at <code>str</code>. This procedure returns the number -of scan lines copied, or <0 for an error. <code>str</code> need not be aligned.</p> - -<blockquote> -<pre>int gdev_prn_get_bits(gx_device_printer *pdev, int y, byte *str, - byte **actual_data)</pre> -</blockquote> - -<p> -This procedure reads out exactly one scan line. If the scan line is -available in the correct format already, <code>*actual_data</code> is -set to point to it; otherwise, the scan line is copied to the buffer -starting at <code>str</code>, and <code>*actual_data</code> is set to -<code>str</code>. This saves a copying step most of the time. -<code>str</code> need not be aligned; however, if -<code>*actual_data</code> is set to point to an existing scan line, it -will be aligned. (See the description of the <code>get_bits</code> -procedure below for more details.)</p> - -<p> -In either of these two cases, each row of the image is stored in the -form described in the comment under <code>gx_tile_bitmap</code> above; -each pixel takes the number of bits specified as <code>color_info.depth</code> -in the device structure, and holds values returned by the device's -<code>encode_color</code> procedure.</p> - -<p> -The <code>print_page</code> procedure can determine the number of bytes -required to hold a scan line by calling:</p> - -<blockquote> -<pre>uint gdev_prn_raster(gx_device_printer *)</pre> -</blockquote> - -<p> -For a very simple concrete example of this pattern of use, we suggest -reading the code in <code>bit_print_page</code> in -<a href="../devices/gdevbit.c">gdevbit.c</a>.</p> - -<p> -If the device provides <code>print_page</code>, Ghostscript will call -<code>print_page</code> the requisite number of times to print the -desired number of copies; if the device provides -<code>print_page_copies</code>, Ghostscript will call -<code>print_page_copies</code> once per page, passing it the desired -number of copies.</p> -<hr> -<h2><a name="Printer_drivers_mt"></a>Printer drivers (Multi-threaded)</h2> - -<p><strong>This interface is new, and subject to change without notice.</strong></p> - -<p>Ghostscript has supported multi-threaded rendering (controlled by the -<a href="Language.htm#Banding_parameters"><tt>-dNumRenderingThreads</tt></a> -command line option) since version 8.64. This uses multiple threads -of execution to accelerate the rendering phase of operations, but driver -specific operations (such as compression) have not been able to benefit in -the same way.</p> - -<p>As from Ghostscript 9.11 onwards, a new device function, <tt>process_page</tt> -has been introduced to solve this. A printer driver will be called via the -<tt>print_page</tt> or <tt>print_page_copies</tt> entry point as before, but -rather than requesting a rectangle of pixels at a time (by -calling <tt>get_bits_rectangle</tt>), the -driver can now invite Ghostscript to "process the page" in whatever sized -chunks it chooses.</p> - -<p>While the benefits of <tt>process_page</tt> come from its use with -multiple rendering threads, it will work perfectly well in single threaded -mode too. Devices do not need to implement both schemes.</p> - -<blockquote> -<pre>int (*process_page)(gx_device *dev, gx_process_page_options_t *options)</pre> -</blockquote> - -<p>The device should fill out a <tt>gx_process_page_options_t</tt> -structure and pass the address of this to the <tt>process_page</tt> -function. The entries within this structure will control exactly how -Ghostscript will process the page. For forwards compatibility devices -should ensure that any unknown fields/option bits within the structure -are initialised to 0.</p> - -<blockquote> -<pre>typedef struct gx_process_page_options_s gx_process_page_options_t; - -struct gx_process_page_options_s -{ - int (*init_buffer_fn)(void *arg, gx_device *dev, gs_memory_t *memory, int w, int h, void **buffer); - void (*free_buffer_fn)(void *arg, gx_device *dev, gs_memory_t *memory, void *buffer); - int (*process_fn)(void *arg, gx_device *dev, gx_device *bdev, const gs_int_rect *rect, void *buffer); - int (*output_fn)(void *arg, gx_device *dev, void *buffer); - void *arg; - int options; /* A mask of GX_PROCPAGE_... options bits */ -};</pre> -</blockquote> - -<p>Ghostscript is free to process the page in 1 or more sections. The potential -benefits of <tt>process_page</tt> come when Ghostscript chooses to use more than -1 section (or "band") and shares the job of rendering these bands between a set -of rendering threads. The overall scheme of operation is as follows:</p> - -<ul> -<li>Ghostscript will call <tt>init_buffer_fn</tt> in turn, once for each rendering -thread in use. This function should (as far as possible) allocate any buffering -that may be required to cope with a band of the given size.</li> - -<li>For each band rendered, Ghostscript will call <tt>process_fn</tt> to -process the given rectangle of the page into the buffer. To achieve this -<tt>process_fn</tt> is passed a buffer device that contains the rendered -version of that rectangle (with the y range adjusted to start from 0). -<tt>process_fn</tt> should call <tt>get_bits_rectangle</tt> as usual to -extract the rendered area. If the options to this call are set correctly -(using <tt>GB_RETURN_POINTER</tt>) no copying or additional storage will -be required. All the calls to <tt>process_fn</tt> will be for -non-overlapping rectangles that cover the page, hence <tt>process_fn</tt> -may overwrite the storage used in the returned buffer device as part -of the processing. Several calls to <tt>process_fn</tt> may take place -simultaneously in different threads, and there is no guarantee that they -will happen 'in order'.</li> - -<li>Ghostscript will call <tt>output_fn</tt> for each band in turn, -passing in the processed buffer containing the output of the -<tt>process_fn</tt> stage. These calls are guaranteed to happen 'in order', -and will be interleaved arbitrarily with the <tt>process_fn</tt> calls. -Once an <tt>output_fn</tt> returns, the buffer may instantly be reused -for another <tt>process_fn</tt> calls.</li> - -<li>Once the page has been processed, Ghostscript will call -<tt>free_buffer_fn</tt> for each allocated buffer to allow the device to -clean up.</li> -</ul> - -<p>At the time of writing the only defined bit in the options word is -<tt>GX_PROCPAGE_BOTTOM_UP</tt> which signifies that Ghostscript should -render bands from the bottom of the page to the top, rather than the -default top to bottom.</p> - -<p>The height of the bands used by Ghostscript when rendering the page -can either be specified by the device itself (using the <tt>band_params</tt> -structure), or can be calculated by Ghostscript based upon the space -available to it. It can sometimes be much easier/more efficient to code -a device if the band height can be relied upon to take only particular -values - for instance, a device that downscales its output will prefer -the height to be a multiple of the downscale used, or a device that uses -DCT based compression may prefer a multiple of 8.</p> - -<p>To accommodate such needs, before Ghostscript sets up its buffers, -it will perform a <tt>gxdso_adjust_bandheight</tt> call. A device can -catch this call to adjust the calculated band height to a value it would -prefer. To avoid invalidating the calculated memory bounds this should -generally be a 'fine' adjustment, and always downwards.</p> - -<p>A simple example of how to use process_page may be found as the -<tt>fpng</tt> device. Within this device:</p> - -<ul> -<li>The <tt>init_buffer_fn</tt> allocates a buffer large enough to -hold the compressed version of each band.</li> - -<li>The <tt>process_fn</tt> applies the sub/paeth filters to the -buffered image, then compresses each band with zlib.</li> - -<li>The <tt>output_fn</tt> simply writes each compressed buffer to -the file.</li> - -<li>The <tt>free_buffer_fn</tt> frees the buffers.</li> - -<li>In addition, the downscaler is called to demonstrate that it is -possible to 'chain' process_page functions.</li> -</ul> - -<p>The <tt>fpng</tt> device is broadly equivalent to the <tt>png16m</tt> -device, but performs much better when multiple threads are in use. -Compression is potentially worse than with <tt>png16m</tt> due to -each band being compressed separately.</p> - -<p>While the <tt>print_page</tt> entry point is specific to printer -devices, the <tt>process_page</tt> device entry point is not. It will, -however, only be useful for devices that involve rendering the page. -As such, neither -dNumRenderingThreads or <tt>process_page</tt> will -help accelerate devices such as <tt>pdfwrite</tt> or <tt>ps2write</tt>.</p> - -<hr> - -<h2><a name="Driver_procedures"></a>Driver procedures</h2> - -<p> -Most of the procedures that a driver may implement are optional. If a -device doesn't supply an optional procedure <code>WXYZ</code>, the entry -in the procedure structure may be either <code>gx_default_WXYZ</code>, -for instance <code>gx_default_strip_tile_rectangle</code>, or -<code>NULL</code> or 0. (The device procedure must also call the -<code>gx_default_</code> procedure if it doesn't implement the function -for particular values of the arguments.) Since, by construction, -device procedure entries are set to 0 at creation time, ones that are -not explicitly initialised will continue to work even if new (optional) -members are added.</p> - -<h3><a name="Life_cycle"></a>Life cycle</h3> - -<p> -When a device is first created, it will have an empty device procs -table. The system will call the device's <code>initialize_device_procs</code> -function pointer to fill out this table. This operation can never fail.</p> - -<p>NOTE: This operation is also used for creating temporary 'prototype' -devices for copying device procedures from.</p> - -<p> -A device instance begins life in a closed state. In this state, no output -operations will occur. Only the following procedures may be called:</p> - -<blockquote><code> -initialize_device<br> -open_device<br> -get_initial_matrix<br> -get_params<br> -put_params<br> -get_hardware_params -</code></blockquote> - -<p> -When <code>setdevice</code> installs a device instance in the graphics -state, it checks whether the instance is closed or open. If the instance -is closed, <code>setdevice</code> calls the open routine, and then sets -the state to open.</p> - -<p> -There is no user-accessible operation to close a device instance. This is -not an oversight – it is required in order to enforce the following -invariant:</p> - -<blockquote> -If a device instance is the current device in <em>any</em> graphics state, -it must be open (have <code>is_open</code> set to true). -</blockquote> - -<p> -Device instances are only closed when they are about to -be freed, which occurs in three situations:</p> - -<ul> -<li>When a <code>restore</code> occurs, if the instance was created since -the corresponding <code>save</code> and is in a VM being restored. I.e., -if the instance was created in local VM since a <code>save</code>, it -will always be closed and freed by the corresponding -<code>restore</code>; if it was created in global VM, it will only be -closed by the outermost <code>restore</code>, regardless of the save -level at the time the instance was created.</li> - -<li>By the garbage collector, if the instance is no longer accessible.</li> - -<li>When Ghostscript exits (terminates).</li> -</ul> - -<h3><a name="Open_close"></a>Open, close, sync, copy</h3> - -<dl> -<dt><code>void (*initialize_device_procs)(gx_device *dev)</code></dt> <dd>Called -once a new device instance has been created. The function should initialize -the device procedure tables. This cannot fail. -<b>NOTE</b>: Clients should rarely need to call a device's -<code>initialize_device_procs</code> procedure: this procedure is mostly used -by the internal device creation code. The sole exception here is when -a device implementation wishes to copy device function pointers from another -device; then a blank <code>gx_device</code> can be created, and -<code>initialize_device_procs</code> can be used to fill out the device procs -table so it can be copied from.</dd> -</dl> - -<dl> -<dt><code>int (*initialize_device)(gx_device *dev)</code> <b><em>[OPTIONAL</em></b></dt> -<dd>Called once a new device instance has been created and the device procs -table has been initialized. This function should perform the minimum -initialization to any internal device state required. If the initial setup -fails, this procedure should return an error; the new instance will be freed. -<b>NOTE</b>: Clients should never call a device's <code>initialize_device</code> -procedure: this procedure is only intended for use by the internal device -creation code.</dd> -</dl> - -<dl> -<dt><code>int (*open_device)(gx_device *)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Open the device: do any initialization associated with making the device -instance valid. This must be done before any output to the device. The -default implementation does nothing. <b>NOTE</b>: Clients should never call -a device's <code>open_device</code> procedure directly: they should -always call <code>gs_opendevice</code> instead.</dd> -</dl> - -<dl> -<dt><code>void (*get_initial_matrix)(gx_device *, gs_matrix *)</code> <b><em>[OPTIONAL]</em></b> </dt> -<dd>Construct the initial transformation matrix mapping user coordinates -(nominally 1/72 inch per unit) to device coordinates. The default -procedure computes this from width, height, and -[<code>xy</code>]<code>_pixels_per_inch</code> on the assumption that -the origin is in the upper left corner, that is -<blockquote> -<code>xx</code> = <code>x_pixels_per_inch</code>/72, <code>xy</code> = 0,<br> -<code>yx = 0, yy = -y_pixels_per_inch</code>/72,<br> -<code>tx = 0, ty = height</code>. -</blockquote> -</dd> -</dl> - -<dl> -<dt><code>int (*sync_output)(gx_device *)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Synchronize the device. If any output to the device has been -buffered, send or write it now. Note that this may be called several times -in the process of constructing a page, so printer drivers should <b>not</b> -implement this by printing the page. The default implementation does -nothing.</dd> -</dl> - -<dl> -<dt><code>int (*output_page)(gx_device *, int num_copies, int flush)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Output a fully composed page to the device. The -<code>num_copies</code> argument is the number of copies that should be -produced for a hardcopy device. (This may be ignored if the driver has -some other way to specify the number of copies.) The <code>flush</code> -argument is true for <code>showpage</code>, false for -<code>copypage</code>. The default definition just calls -<code>sync_output</code>. Printer drivers should implement this by -printing and ejecting the page.</dd> -</dl> - -<dl> -<dt><code>int (*close_device)(gx_device *)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Close the device: release any associated resources. After this, output -to the device is no longer allowed. The default implementation does -nothing. <b>NOTE</b>: Clients should never call a device's -<code>close_device</code> procedure directly: they should always call -<code>gs_closedevice</code> instead. </dd> -</dl> -<h3><a name="Color_mapping"></a>Color and alpha mapping</h3> - -<p> -Note that code in the Ghostscript library may cache the results of calling -one or more of the color mapping procedures. If the result returned by any -of these procedures would change (other than as a result of a change made by -the driver's <code>put_params</code> procedure), the driver must call -<code>gx_device_decache_colors(dev)</code>.</p> - -<p> -The <code>map_rgb_color</code>, <code>map_color_rgb</code>, and -<code>map_cmyk_color</code> are obsolete. They have been left -in the device procedure list for backward compatibility. See the -<code>encode_color</code> and <code>decode_color</code> procedures -below. To insure that older device drivers are changed to use the new -<code>encode_color</code> and <code>decode_color</code> -procedures, -the parameters for the older procedures have been changed to -match the new procedures. To minimize changes in devices that have -already been written, the map_rgb_color and map_cmyk_color routines -are used as the default value for the encode_color routine. The -map_cmyk_color routine is used if the number of components is four. -The map_rgb_color routine is used if the number of components is one -or three. This works okay for RGB and CMYK process color model devices. -However this does not work properly for gray devices. The encode_color -routine for a gray device is only passed one component. Thus the -map_rgb_color routine must be modified to only use a single input (instead -of three). (See the encode_color and decode_color routines below.)</p> - - -<p> -Colors can be specified to the Ghostscript graphics library in a variety -of forms. For example, there are a wide variety of color spaces that can -be used such as Gray, RGB, CMYK, DeviceN, Separation, Indexed, CIEbasedABC, -etc. The graphics library converts the various input color space -values into four base color spaces: Gray, RGB, CMYK, and DeviceN. The -DeviceN color space allows for specifying values for individual device -colorants or spot colors.</p> - -<p> -Colors are converted by the device in a two step process. The first step -is to convert a color in one of the base color spaces (Gray, RGB, CMYK, -or DeviceN) into values for each device colorant. This transformation is -done via a set of procedures provided by the device. These procedures are -provided by the <code>get_color_mapping_procs</code> device procedure.</p> - -<p> -Between the first and second steps, the graphics library applies transfer -functions to the device colorants. Where needed, the output of the results -after the transfer functions is used by the graphics library for halftoning.</p> - -<p> -In the second step, the device procedure <code>encode_color</code> is -used to convert the transfer function results into a -<code>gx_color_index</code> value. -The <code>gx_color_index</code> values are passed to specify colors -to various routines. -The choice of the encoding for a <code>gx_color_index</code> is -up to the device. Common choices are indexes into a color palette or -several integers packed together into a single value. The manner of this -encoding is usually opaque to the graphics library. The only exception to this -statement occurs when halftoning 5 or more colorants. In this case the -graphics library assumes that if a colorant values is zero then the -bits associated with the colorant in the <code>gx_color_index</code> -value are zero.</p> - -<dl> -<dt><code>int get_color_comp_index(const gx_device * dev, const char * pname, -int name_size, int src_index)</code> <b><em>[OPTIONAL]</em></b> </dt> -<dd>This procedure returns the device colorant number of the given name. -The possible return values are -1, 0 to -<code>GX_DEVICE_COLOR_MAX_COMPONENTS - 1</code>, or -<code>GX_DEVICE_COLOR_MAX_COMPONENTS</code>. A value of -1 indicates that -the specified name is not a colorant for the device. A value of 0 to -<code>GX_DEVICE_COLOR_MAX_COMPONENTS - 1</code> indicates the colorant number -of the given name. A value of <code>GX_DEVICE_COLOR_MAX_COMPONENTS</code> -indicates that the given name is a valid colorant name for the device but the -colorant is not currently being used. This is used for implementing names -which are in SeparationColorNames but not in SeparationOrder. - -<p> -The default procedure returns results based upon process color model -of DeviceGray, DeviceRGB, or DeviceCMYK selected by -<code>color_info.num_components</code>. This procedure must be -defined if another process color model is used by the device or spot colors are -supported by the device.</p> -</dd> -</dl> - -<dl> -<dt><code>const gx_cm_color_map_procs * get_color_mapping_procs(const -gx_device * dev, const gx_device ** tdev)</code> <b><em>[OPTIONAL]</em></b> </dt> -<dd>This procedure returns a list of three procedures, together with the -device to pass to them. These procedures are used to translate values in -either Gray, RGB, or CMYK color spaces into device colorant values. A -separate procedure is not required for the DeviceN and Separation color -spaces since these already represent device colorants. - -<p>In many cases, the device returned in <code>tdev</code> will be the -same as <code>dev</code>, but the caller should not rely on this. For -cases where we have a chain of devices (perhaps because of a subclass -or compositor device having been introduced internally as part of the -rendering process), the actual device that needs to do the color mapping -may be a child device of the original one. In such cases <code>tdev</code> -will be returned as a different value to <code>dev</code>. -</p> - -<p> -The default procedure returns a list of procedures based upon -<code>color_info.num_components</code>. These procedures are appropriate -for DeviceGray, DeviceRGB, or DeviceCMYK process color model devices. A -procedure must be defined if another process color model is used by the -device or spot colors are to be supported. All these procedures take a -<code>gx_device</code> pointer; these should be called with the value -returned in <code>tdev</code> NOT the initial value of <code>dev</code>.</p> -</dd> -</dl> - -<dl> -<dt><code>gx_color_index (*encode_color)(gx_device * dev, -gx_color_value * cv)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Map a set of device color values into a <code>gx_color_index</code> -value. The range of legal values of the -arguments is 0 to <code>gx_max_color_value</code>. The default procedure -packs bits into a <code>gx_color_index</code> value based upon the -values in <code>color_info.depth</code> and -<code>color_info.num_components</code>. - -<p> -Note that the <code>encode_color</code> procedure -must not return <code>gx_no_color_index</code> (all 1s).</p> -</dd> -</dl> - -<dl> -<dt><code>int (*decode_color)(gx_device *, gx_color_index color, -gx_color_value * CV)</code> <b><em>[OPTIONAL]</em></b> </dt> -<dd>This is the inverse of the <code>encode_color</code> procedure. -Map a <code>gx_color_index</code> value to color values. The default -procedure unpacks bits from the <code>gx_color_index</code> value based upon -the values in <code>color_info.depth</code> and -<code>color_info.num_components</code>.</dd> -</dl> - -<dl> -<dt><code>typedef enum { go_text, -go_graphics } graphic_object_type; int -(*get_alpha_bits)(gx_device *dev, -graphic_object_type type)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>This procedure returns the number of bits to use for anti-aliasing. -The default implementation simply returns the color_info.anti_alias -member of the driver structure.</dd> -</dl> - -<dl> -<dt><code>void (*update_spot_equivalent_colors)(gx_device *, -const gs_state *)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>This routine provides a method for the device to gather an equivalent -color for spot colorants. This routine is called when a Separation or DeviceN -color space is installed. See comments at the start of -<a href="../base/gsequivc.c">gsequivc.c</a>. Note: This procedure is only needed -for devices that support spot colorants and also need to have an equivalent -color for simulating the appearance of the spot colorants.</dd> -</dl> - -<h3><a name="Pixel_level_drawing"></a>Pixel-level drawing</h3> - -<p> -This group of drawing operations specifies data at the pixel level. All -drawing operations use device coordinates and device color values.</p> - -<dl> -<dt><code>int (*fill_rectangle)(gx_device *, int x, -int y, int width, int height, -gx_color_index color)</code></dt> -<dd>Fill a rectangle with a color. The set of pixels filled is {(px,py) | -x <= px < x + width and y <= py < y + height}. In other words, -the point <em>(x,y)</em> is included in the rectangle, as are -<em>(x+w-1,y)</em>, <em>(x,y+h-1)</em>, and <em>(x+w-1,y+h-1)</em>, but -<b><em>not</em></b> <em>(x+w,y)</em>, <em>(x,y+h)</em>, or -<em>(x+w,y+h)</em>. If <code>width</code> <= 0 or -height <= 0, <code>fill_rectangle</code> should return 0 -without drawing anything. - -<p> -Note that <code>fill_rectangle</code> is the only non-optional procedure -in the driver interface.</p> -</dd> -</dl> - -<h4><a name="Bitmap_imaging"></a>Bitmap imaging</h4> - -<p> -Bitmap (or pixmap) images are stored in memory in a nearly standard way. -The first byte corresponds to <em>(0,0)</em> in the image coordinate -system: bits (or polybit color values) are packed into it left to right. -There may be padding at the end of each scan line: the distance from one -scan line to the next is always passed as an explicit argument.</p> - -<dl> -<dt><code>int (*copy_mono)(gx_device *, -const unsigned char *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height, gx_color_index color0, -gx_color_index color1)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Copy a monochrome image (similar to the PostScript image operator). -Each scan line is raster bytes wide. Copying begins at -(<code>data_x</code>,0) and transfers a rectangle of the given width and -height to the device at device coordinate <em>(x,y)</em>. (If the transfer -should start at some non-zero y value in the data, the caller can adjust -the data address by the appropriate multiple of the raster.) The copying -operation writes device color <code>color0</code> at each 0-bit, and -<code>color1</code> at each 1-bit: if <code>color0</code> or -<code>color1</code> is <code>gx_no_color_index</code>, the device -pixel is unaffected if the image bit is 0 or 1 respectively. If -<code>id</code> is different from <code>gx_no_bitmap_id</code>, it -identifies the bitmap contents unambiguously; a call with the same -<code>id</code> will always have the same <code>data</code>, -<code>raster</code>, and data contents. - -<p> -This operation, with -<code>color0</code> = <code>gx_no_color_index</code>, is -the workhorse for text display in Ghostscript, so implementing it -efficiently is very important.</p> -</dd> -</dl> - -<dl> -<dt><code>int (*strip_tile_rectangle)(gx_device *, -const gx_strip_bitmap *tile, int x, int y, -int width, int height, gx_color_index color0, -gx_color_index color1, int phase_x, int phase_y)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>Tile a rectangle. Tiling consists of doing multiple -<code>copy_mono</code> operations to fill the rectangle with copies of -the tile. The tiles are aligned with the device coordinate system, to -avoid "seams". Specifically, the (<code>phase_x</code>, -<code>phase_y</code>) point of the tile is aligned with the origin of -the device coordinate system. (Note that this is backwards from the -PostScript definition of halftone phase.) <code>phase_x</code> and -<code>phase_y</code> are guaranteed to be in the range -<em>[0..</em><code>tile->width</code><em>)</em> and -<em>[0..</em><code>tile->height</code><em>)</em> respectively. - -<p> -If <code>color0</code> and <code>color1</code> are both -<code>gx_no_color_index</code>, then the tile is a color pixmap, not a -bitmap: see the next section.</p> - -<p> -This operation is the workhorse for halftone filling in Ghostscript, so -implementing it efficiently for solid tiles (that is, where either -<code>color0</code> and <code>color1</code> are both -<code>gx_no_color_index</code>, for colored halftones, or neither one is -<code>gx_no_color_index</code>, for monochrome halftones) is very -important.</p> -</dd> -</dl> - -<h4><a name="Pixmap_imaging"></a>Pixmap imaging</h4> - -<p> -Pixmaps are just like bitmaps, except that each pixel may occupy more than -one bit. In "chunky" or "Z format", all the bits for each pixel are grouped -together. For <code>copy_color</code>, the number of bits per pixel is given -by the <code>color_info.depth</code> parameter in the device structure. The -legal values are 1, 2, 4, 8, 16, 24, 32, 40, 48, 56, or 64. The pixel values -are device color codes (that is, whatever it is that <code>encode_color</code> returns). -<br><br> -If the data is planar, then each plane is contiguous, and the number -of planes is given by <code>color_info.num_components</code>. The bits per -component is <code>depth/num_components</code>.</p> - -<dl> -<dt><code>int (*copy_color)(gx_device *, -const unsigned char *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Copy a color image with multiple bits per pixel. The raster is in -bytes, but <code>x</code> and <code>width</code> are in pixels, not -bits. If <code>id</code> is different from -<code>gx_no_bitmap_id</code>, it identifies the bitmap contents -unambiguously; a call with the same <code>id</code> will always have the -same <code>data</code>, <code>raster</code>, and data contents.</dd> -</dl> - -<dl> -<dt><code>int (*copy_planes)(gx_device *, -const unsigned char *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height, int plane_height)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Copy an image with data stored in planar format. The raster is in -bytes, but <code>x</code> and <code>width</code> are in pixels, not -bits. If <code>id</code> is different from <code>gx_no_bitmap_id</code>, -it identifies the bitmap contents unambiguously; a call with the same -<code>id</code> will always have the same <code>data</code>, <code>raster</code>, -and data contents.<br><br> -Each plane is <code>depth/num_components</code> number of bits and the distance between -planes is <code>plane_height</code> number of rows. The height is always less -than or equal to the plane_height.</dd> -</dl> - -<p> -We do not provide a separate procedure for tiling with a pixmap; instead, -<code>strip_tile_rectangle</code> can also take colored tiles. This is -indicated by the <code>color0</code> and <code>color1</code> -arguments' both being <code>gx_no_color_index</code>. In this case, as -for <code>copy_color</code>, the <code>raster</code> and -<code>height</code> in the "bitmap" are interpreted as for real bitmaps, -but the <code>x</code> and <code>width</code> are in pixels, not -bits.</p> - -<dl> -<dt> -<code> -<pre> -typedef enum { - transform_pixel_region_begin = 0, - transform_pixel_region_data_needed = 1, - transform_pixel_region_process_data = 2, - transform_pixel_region_end = 3 - } transform_pixel_region_reason; -typedef struct { - void *state; - union { - struct { - const gs_int_rect *clip; - int w; /* source width */ - int h; /* source height */ - int spp; - const gx_dda_fixed_point *pixels; /* DDA to enumerate the destination positions of pixels across a row */ - const gx_dda_fixed_point *rows; /* DDA to enumerate the starting position of each row */ - gs_logical_operation_t lop; - } init; - struct { - const unsigned char *buffer[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int data_x; - gx_cmapper_t *cmapper; - const gs_gstate *pgs; - } process_data; - } u; -} transform_pixel_region_data; -</pre> -int (*transform_pixel_region)(gx_device *, -transform_pixel_reason, transform_pixel_reason_data *data)</code> <b><em>[OPTIONAL]</em></b> -<dd>Transform a 2-dimensional region of pixels into the destination. -Given a 2d source block of pixels (supplied as scanline data), this -function transforms that data, maps it through the supplied colour -lookup function, clips it, and plots it into the device. - -<p>In all calls to this function a negative return value indicates an error.</p> - -<p>Called first with the <code>transform_pixel_region_init</code> reason code, -this prepares for subsequent calls to scale a region as described in the -<code>data.u.init</code> structure. A pointer to any state required for -this should be written into <code>data.state</code>, and the caller must -pass that in to subsequent calls.</p> - -<p>Subsequently this will be called with <code>transform_pixel_region_data_needed</code>. -The function will then check to see if the next scanline of data will be trivially -clipped away. If so, then it will return zero to indicate that it is not needed. -This can help the caller to avoid unnecessary processing. A positive return value -indicates that the line is required.</p> - -<p>For every line where the data is required, the function will be called with -<code>transform_pixel_region_process_data</code>. The function will then read -and process the line from <code>data.u.process_data</code>. -The data in the buffer is packed 8 bit values, which will be fed into the supplied -<code>cmapper</code> to set the device color as required. This is then written -into the device.</p> - -<p>Once all the scanlines have been fed through calls to <code>transform_pixel_region_data_needed</code> -and <code>transform_pixel_region_process_data</code>, a final call with <code>transform_pixel_region_end</code> -is made that frees the state.</p> - -<p>The default implementation of this device function will generally break the pixel -data down into calls to <code>fill_rectangle</code>, though in some cases (notably -the portrait 8 bit per component output case), a faster route through <code>copy_color</code> -can be used.</p> - -<p>Memory devices offer a version of this device function that can accelerate direct -plotting to the memory array.</p> - -<p>NOTE: Currently the clipping rectangle is not honoured for skewed (not portrait or landscape) -transformations. This is allowed for in the callers. -</p> -</dd> - -</dl> - -<h4><a name="Compositing"></a>Compositing</h4> - -<p> -In addition to direct writing of opaque pixels, devices must also support -compositing. Currently two kinds of compositing are defined -(<code>RasterOp</code> and alpha-based), but more may be added in the -future.</p> - -<dl> -<dt><code>int (*copy_alpha)(gx_device *dev, -const unsigned char *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height, gx_color_index color, int depth)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>This procedure is somewhat misnamed: it was added to the interface -before we really understood alpha channel and compositing. - -<p> -Fill a given region with a given color modified by an individual alpha -value for each pixel. For each pixel, this is equivalent to -alpha-compositing with a source pixel whose alpha value is obtained from -the pixmap (<code>data</code>, <code>data_x</code>, and -<code>raster</code>) and whose color is the given color (which has -<b><em>not</em></b> been premultiplied by the alpha value), using the Sover -rule.</p> - -<p><code>depth</code>, the number of bits per alpha value, is either -2, 4 or 8. Any <code>copy_alpha</code> routine must accept being called -with an 8 bit depth. In addition they should accept either 2 or 4 if -the corresponding <code>get_alpha_bits</code> procedure returns either -of those values.</p> -</dd> -</dl> - -<dl> -<dt><code>int (*copy_alpha_hl_color)(gx_device *dev, -const byte *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height, const gx_drawing_color *pdcolor, int depth)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>Equivalent function to copy_alpha, using high level color rather -than a gx_color_index.</dd> -</dl> - -<dl> -<dt><code>int (*composite)(dev_t *dev, -gx_device_t **pcdev, const gs_composite_t *pcte, -const gs_imager_state *pis, gs_memory_t *memory)</code> -<b><em>[OPTIONAL]</em></b> </dt> -<dd>Requests that a device perform a compositing operation; the device -should composite data written to it with the device's existing data, -according to the compositing function defined by <code>*pcte</code>. -If a device cannot perform such an operation itself, it will create a -compositor device to wrap itself that will perform such operations for -it. Accordingly, the caller must watch the return values from this -function to understand if a new device has been created to which future -calls should be made. -<p> -Devices will normally implement this in one of the following standard ways: - -<ul> -<li>Devices that don't do any imaging and don't forward any imaging -operations (for example, the null device, the hit detection device, and the -clipping list accumulation device) simply set *pcdev to themselves, and -return 0, which effectively ignores the compositing function.</li> - -<li>"Leaf" devices that do imaging and have no special optimizations for -compositing (for example, some memory devices) ask the -<code>gs_composite_t</code> to create a default compositor device that -'wraps' the current device. They put this in <code>*pcdev</code> and -return 1.</li> - -<li>Leaf devices that can implement some kinds of compositing operation -efficiently (for example, monobit memory devices and RasterOp) inspect the -type and values of <code>*pcte</code> to determine whether it specifies -such an operation: if so, they create a specialized compositor, and if not, -they ask the <code>gs_composite_t</code> to create a default compositor. They -place this in <code>*pcdev</code> and return 1.</li> -</ul> - -<p>In short, on every non-error return, <code>*pcdev</code> will be set -either to the leaf device (in the case where no special compositing is -required), or to the device that does the compositing. If the return -code is 1, then <code>*pcdev</code> is a new device that was created -to wrap <code>dev</code> to perform the compositing for it. Callers -may need to spot this case so as to update which device future -operations are sent to.</p> - -<p>For forwarding devices, for example, if the call returns 1, then -they should update their target device to be the new device. For the -graphics library, if the call returns 1, then it should update the -current device to be the new one.</p> - -<p> -Other kinds of forwarding devices, which don't fall into any of these -categories, require special treatment. In principle, what they do is ask -their target to create a compositor, and then create and return a copy of -themselves with the target's new compositor as the target of the copy. -There is a possible default implementation of this approach: if the -original device was <b>D</b> with target <b>T</b>, and <b>T</b> creates a -compositor <b>C</b>, then the default implementation creates a device -<b>F</b> that for each operation temporarily changes <b>D</b>'s target to -<b>C</b>, forwards the operation to <b>D</b>, and then changes <b>D</b>'s -target back to <b>T</b>. However, the Ghostscript library currently only -creates a compositor with an imaging forwarding device as target in a few -specialized situations (banding, and bounding box computation), and these -are handled as special cases.</p> - -<p> -Note that the compositor may have a different color space, color -representation, or bit depth from the device to which it is compositing. -For example, alpha-compositing devices use standard-format chunky color -even if the underlying device doesn't.</p> - -<p> -Closing a compositor frees all of its storage, including the compositor -itself. However, since the <code>composite</code> call may -return the same device, clients must check for this case, and only call the -close procedure if a separate device was created.</p> -</dd> -</dl> - -<h3><a name="Polygon_level_drawing"></a>Polygon-level drawing</h3> - -<p> -In addition to the pixel-level drawing operations that take integer device -coordinates and pure device colors, the driver interface includes -higher-level operations that draw polygons using fixed-point coordinates, -possibly halftoned colors, and possibly a non-default logical operation.</p> - -<p> -The <code>fill_</code>* drawing operations all use the center-of-pixel -rule: a pixel is colored iff its center falls within the polygonal region -being filled. If a pixel center <em>(X+0.5,Y+0.5)</em> falls exactly on -the boundary, the pixel is filled iff the boundary is horizontal and the -filled region is above it, or the boundary is not horizontal and the filled -region is to the right of it.</p> - -<dl> -<dt><code>int (*fill_trapezoid)(gx_device *dev, const -gs_fixed_edge *left, const gs_fixed_edge *right, -fixed ybot, fixed ytop, bool swap_axes, -const gx_drawing_color *pdcolor, -gs_logical_operation_t lop)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Fill a trapezoid. The bottom and top edges are parallel to the x -axis, and are defined by <code>ybot</code> and <code>ytop</code>, -respectively. The left and right edges are defined by <code>left</code> -and <code>right</code>. Both of these represent lines (<code>gs_fixed_edge</code> -is defined in <a href="../base/gxdevcli.h">gxdevcli.h</a> and consists -of <code>gs_fixed_point</code> <code>start</code> and <code>end</code> points). -The y coordinates of these lines need not have any specific relation to -<code>ybot</code> and <code>ytop</code>. The routine is defined this way so -that the filling algorithm can subdivide edges and still guarantee -that the exact same pixels will be filled. If -<code>swap_axes</code> is set, the meanings of X and Y are -interchanged. -</dd> - -<dt><code>int (*fill_parallelogram)(gx_device *dev, -fixed px, fixed py, fixed ax, fixed ay, fixed bx, -fixed by, const gx_drawing_color *pdcolor, -gs_logical_operation_t lop)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Fill a parallelogram whose corners are <em>(px,py)</em>, -<em>(px+ax,py+ay)</em>, <em>(px+bx,py+by)</em>, and -<em>(px+ax+bx,py+ay+by)</em>. There are no constraints on the values of -any of the parameters, so the parallelogram may have any orientation -relative to the coordinate axes.</dd> - -<dt><code>int (*fill_triangle)(gx_device *dev, fixed px, -fixed py, fixed ax, fixed ay, fixed bx, fixed by, -const gx_drawing_color *pdcolor, -gs_logical_operation_t lop)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Fill a triangle whose corners are <em>(px,py)</em>, -<em>(px+ax,py+ay)</em>, and <em>(px+bx,py+by)</em>.</dd> - -<dt><code>int (*draw_thin_line)(gx_device *dev, -fixed fx0, fixed fy0, fixed fx1, fixed fy1, -const gx_drawing_color *pdcolor, -gs_logical_operation_t lop)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Draw a one-pixel-wide line from <em>(fx0,fy0)</em> to -<em>(fx1,fy1)</em>.</dd></dl> - -<dl><dt></dt><dd> - -<h3><a name="Linear_color_drawing"></a>Linear color drawing</h3> - -<p> -Linear color functions allow fast high quality rendering of -shadings on continuous tone devices. They implement filling simple areas -with a lineary varying color. These functions are not called if the device applies halftones, -or uses a non-separable or a non-linear color model.</p> - -<dl> -<dt><code> int (*fill_linear_color_triangle) - (dev_t *dev, const gs_fill_attributes *fa, - const gs_fixed_point *p0, const gs_fixed_point *p1, - const gs_fixed_point *p2, - const frac31 *c0, const frac31 *c1, const frac31 *c2) -</code> -<b><em>[OPTIONAL]</em></b></dt> - -<dd>This function is the highest level one within the linear color function group. -It fills a triangle with a linearly varying color. -Arguments specify 3 points in the device space - vertices of a triangle, and their colors. -The colors are represented as vectors of positive fractional numbers, each of which -represents a color component value in the interval <code>[0,1]</code>. -The number of components in a vector in the number of color -components in the device (process) color model.</dd> -<dd> -The implementation fills entire triangle. -The filling rule is same as for <a href="#Polygon_level_drawing">Polygon-level drawing</a>. -The color of each pixel within the triangle is computed as a linear interpolation -of vertex colors.</dd> -<dd> -The implementation may reject the request if the area or the color appears too complex -for filling in a single action. For doing that the implementation returns 0 and must not -paint any pixel. In this case the graphics library will perform a subdivision of the area -into smaller triangles and call the function again with smaller areas.</dd> -<dd> -<b><em>Important note :</em></b> Do not try to decompose the area within -the implementation of <code> fill_linear_color_triangle</code>, because -it can break the plane coverage contiguity and cause a dropout. -Instead request that the graphics library should perform the decomposition. -The graphics libary is smart enough to do that properly.</dd> -<dd> -<b><em>Important note :</em></b> -The implementation must handle a special case, when only 2 colors are specified. -It happens if <code>p2</code> is <code>NULL</code>. -This means that the color does not depend on the X coordinate, -i.e. it forms a linear gradient along the Y axis. -The implementation must not reject (return 0) such cases.</dd> -<dd> -<b><em>Important note :</em></b>The device color component -value 1 may be represented with several hexadecimal values : -<code>0x7FFF0000</code>, <code>0x7FFFF000</code>, <code>0x7FFFFF00</code>, etc., -because the precision here exceeds the color precision of the device. -To convert a <code>frac31</code> value into a device color component value, -fist drop (ignore) the sign bit, then drop least significant bits - -so many ones as you need to fit the device color precision.</dd> -<dd> -<b><em>Important note :</em></b> The <code>fa</code> argument may contain -the <code>swap_axes</code> bit set. In this case the implementation must swap (transpose) -<code>X</code> and <code>Y</code> axes.</dd> -<dd> -<b><em>Important note :</em></b> The implementation must not paint outside the -clipping rectangle specified in the <code>fa</code> argument. -If <code>fa->swap_axes</code> is true, the clipping rectangle is transposed.</dd> -<dd> -See <code> gx_default_fill_linear_color_triangle </code> -in <code>gdevddrw.c</code> for sample code.</dd> -</dl> - - -<dl> -<dt><code> int (*fill_linear_color_trapezoid) - (dev_t *dev, const gs_fill_attributes *fa, - const gs_fixed_point *p0, const gs_fixed_point *p1, - const gs_fixed_point *p2, const gs_fixed_point *p3, - const frac31 *c0, const frac31 *c1, - const frac31 *c2, const frac31 *c2) -</code><b><em>[OPTIONAL]</em></b></dt> - -<dd>This function is a lower level one within the linear color function group. -The default implementation of <code> fill_linear_color_triangle </code> -calls this function 1-2 times per triangle. Besides that, -this function may be called by the graphics library for other special cases, -when a decomposition into triangles appears undesirable.</dd> -<dd> -While the prototype can specify a bilinear color, -we assume that the implementation handles linear colors only. -This means that the implementation can ignore any of <code> c0, c1, c2, c3 </code>. -The graphics library takes a special care of the color linearity -when calling this function. The reason for passing all 4 color arguments -is to avoid color precision problems.</dd> -<dd> -Similarly to <code> fill_linear_color_triangle </code>, -this function may be called with only 2 colors, and may reject areas as being too complex. -All those important notes are applicable here.</dd> -<dd> -Sample code may be found in in <code>gxdtfill.h</code>; be aware it's rather complicated. -A linear color function is generated from it as <code> gx_fill_trapezoid_ns_lc </code> -with the following template parameters : - -<pre> -#define LINEAR_COLOR 1 -#define EDGE_TYPE gs_linear_color_edge -#define FILL_ATTRS const gs_fill_attributes * -#define CONTIGUOUS_FILL 0 -#define SWAP_AXES 0 -#define FILL_DIRECT 1 -</pre> -<p>See the helplers <code>init_gradient</code>, -<code>step_gradient</code> (defined in in <code>gdevddrw.c</code>), how to manage colors.</p> -<p>See <code>check_gradient_overflow</code> -(defined in in <code>gdevddrw.c</code>), as an example of an area -that can't be painted in a single action due to 64-bits fixed overflows.</p> -</dd> -</dl> - -<dl> -<dt><code> int (*fill_linear_color_scanline) - (dev_t *dev, const gs_fill_attributes *fa, - int i, int j, int w, - const frac31 *c0, - const int32_t *c0_f, - const int32_t *cg_num, - int32_t cg_den) -</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>This function is the lowest level one within the linear color function group. -It implements filling a scanline with a linearly varying color. -The default implementation for <code> fill_linear_color_trapezoid </code> -calls this function, and there are no other calls to it from the graphics libary. -Thus if the device implements <code> fill_linear_color_triangle </code> and -<code> fill_linear_color_trapezoid </code> by own means, -this function may be left unimplemented.</dd> -<dd> -<code>i</code> and <code>j</code> specify device coordinates (indices) -of the starting pixel of the scanline, <code>w</code> specifies the -width of the scanline, i.e. the number of pixels to be painted to the right from -the starting pixel, including the starting pixel.</dd> -<dd> -<code>c0</code> specifies the color for the starting pixel -as a vector of fraction values, each of which represents -a color value in the interval <code>[0,1]</code>.</dd> -<dd> -<code>c0_f</code> specify a fraction part of the color for the starting pixel. -See the formula below about using it.</dd> -<dd> -<code>cg_num</code> specify a numerator for the color gradient - -a vector of values in <code>[-1,1]</code>, each of which correspond to a color component.</dd> -<dd> -<code>cg_den</code> specify the denominator for the color gradient - -a value in <code>[-1,1]</code>.</dd> -<dd> -The color for the pixel <code>[i + k, j]</code> to be computed like this : -<pre><code> - (double)(c0[n] + (c0_f[n] + cg_num[n] * k) / cg_den) / (1 ^ 31 - 1) -</code></pre></dd> -<dd>where <code>0 <= k <= w </code>, and <code>n</code> is a device color component index.</dd> - -<dd> -<b><em>Important note :</em></b> The <code>fa</code> argument may contain -the <code>swap_axes</code> bit set. In this case the implementation must swap (transpose) -<code>X</code> and <code>Y</code> axes.</dd> -<dd> -<b><em>Important note :</em></b> The implementation must not paint outside the -clipping rectangle specified in the <code>fa</code> argument. -If <code>fa->swap_axes</code> is true, the clipping rectangle is transposed.</dd> -<dd> -See <code> gx_default_fill_linear_color_scanline</code> -in <code>gdevdsha.c</code> as a sample code.</dd> -</dl> - - -<h3><a name="High_level_drawing"></a>High-level drawing</h3> - -<p> -In addition to the lower-level drawing operations described above, the -driver interface provides a set of high-level operations. Normally these -will have their default implementation, which converts the high-level -operation to the low-level ones just described; however, drivers that -generate high-level (vector) output formats such as pdfwrite, or communicate with devices -that have firmware for higher-level operations such as polygon fills, may -implement these high-level operations directly. For more details, please -consult the source code, specifically:</p> - -<blockquote><table> -<tr valign="top"> <th align="left">Header</th> - - <th align="left">Defines</th></tr> -<tr valign="top"> <td><a href="../base/gxpaint.h">gxpaint.h</a></td> - - <td><code>gx_fill_params</code>, <code>gx_stroke_params</code></td></tr> -<tr valign="top"> <td><a href="../base/gxfixed.h">gxfixed.h</a></td> - - <td><code>fixed</code>, <code>gs_fixed_point</code> (used by - <code>gx_*_params</code>)</td></tr> -<tr valign="top"> <td><a href="../base/gxgstate.h">gxgstate.h</a></td> - - <td><code>gs_imager_state</code> (used by <code>gx_*_params</code>)</td></tr> -<tr valign="top"> <td><a href="../base/gxline.h">gxline.h</a></td> - - <td><code>gx_line_params</code> (used by <code>gs_imager_state</code>)</td></tr> -<tr valign="top"> <td><a href="../base/gslparam.h">gslparam.h</a></td> - - <td>line cap/join values (used by <code>gx_line_params</code>)</td></tr> -<tr valign="top"> <td><a href="../base/gxmatrix.h">gxmatrix.h</a></td> - - <td><code>gs_matrix_fixed</code> (used by <code>gs_imager_state</code>)</td></tr> -<tr valign="top"> <td><a href="../base/gspath.h">gspath.h</a>, <a href="../base/gxpath.h">gxpath.h</a>, <a href="../base/gzpath.h">gzpath.h</a></td> - - <td><code>gx_path</code></td></tr> -<tr valign="top"> <td><a href="../base/gxcpath.h">gxcpath.h</a>, <a href="../base/gzcpath.h">gzcpath.h</a></td> - - <td><code>gx_clip_path</code></td></tr> -</table></blockquote> - -<p> -For a minimal example of how to implement the high-level drawing operations, -see <a href="../devices/gdevtrac.c">gdevtrac.c</a>.</p> - -<h4><a name="Paths"></a>Paths</h4> - -<dl> -<dt><code>int (*fill_path)(gx_device *dev, -const gs_imager_state *pis, gx_path *ppath, -const gx_fill_params *params, -const gx_drawing_color *pdcolor, -const gx_clip_path *pcpath)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Fill the given path, clipped by the given clip path, according to the -given parameters, with the given color. The clip path pointer may be -<code>NULL</code>, meaning do not clip.</dd> -<dd> -The implementation must paint the path with the specified device color, -which may be either a pure color, or a pattern. If the device can't -handle non-pure colors, it should check the color type and -call the default implementation gx_default_fill_path for cases -which it can't handle. The default implementation will perform -a subdivision of the area to be painted, and will -call other device virtual functions (such as fill_linear_color_triangle) -with simpler areas.</dd> - -</dl> - -<dl> -<dt><code>int (*stroke_path)(gx_device *dev, -const gs_imager_state *pis, gx_path *ppath, -const gx_stroke_params *params, -const gx_drawing_color *pdcolor, -const gx_clip_path *pcpath)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Stroke the given path, clipped by the given clip path, according to the -given parameters, with the given color. The clip path pointer may be -<code>NULL</code>, meaning not to clip.</dd> -</dl> - -<dl> -<dt><code>int (*fill_mask)(gx_device *dev, -const byte *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height, const gx_drawing_color *pdcolor, int depth, -int command, const gx_clip_path *pcpath)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>Color the 1-bits in the given mask (or according to the alpha values, -if <code>depth</code> > 1), clipped by the given clip path, -with the given color and logical operation. The clip path pointer may be -<code>NULL</code>, meaning do not clip. The parameters -<code>data</code>, ..., <code>height</code> are as for -<code>copy_mono</code>; depth is as for <code>copy_alpha</code>; -command is as below.</dd> -</dl> - -<h4><a name="F_spec"></a>The function specification f</h4> - -<p> -"Command" indicates the raster operation and transparency as follows:</p> - -<blockquote><table> -<tr valign="bottom"> - <th colspan ="2">Bits</th> -</tr> -<tr valign="top"> <td>7-0</td> - - <td>raster op</td></tr> -<tr valign="top"> <td>8</td> - - <td>0 if source opaque, 1 if source transparent</td></tr> -<tr valign="top"> <td>9</td> - - <td>0 if texture opaque, 1 if texture transparent</td></tr> -<tr valign="top"> <td>10</td> - - <td>1 if pdf transparency is in use, 0 otherwise. This makes no -difference to the rendering, but forces the raster operation to be considered - non-idempotent by internal routines.</td></tr> -<tr valign="top"> <td>11</td> - - <td>1 if the target of this operation is a specific plane, rather -than all planes. The plane in question is given by bits 13 upwards. This -is only used by the planar device.</td></tr> -<tr valign="top"> <td>12-</td> - - <td>If bit 11 = 1, then bits 12 upwards give the plane number to - operate on. Otherwise, should be set to 0.</td></tr> -</table></blockquote> - -<p>In general most devices should just check to see that bits they do not -handle (11 and above typically) are zero, and should jump to the default - implementation, or return an error otherwise.</p> - -<p> -The raster operation follows the Microsoft and H-P specification. It is an -8-element truth table that specifies the output value for each of the -possible 2×2×2 input values as follows:</p> - -<blockquote><table> -<tr valign="bottom"> - <th>Bit</th> - - <th>Texture</th> - - <th>Source</th> - - <th>Destination</th></tr> -<tr valign="top"> <td align="center">7</td> - - <td align="center">1</td> - - <td align="center">1</td> - - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">6</td> - - <td align="center">1</td> - - <td align="center">1</td> - - <td align="center">0</td></tr> -<tr valign="top"> <td align="center">5</td> - - <td align="center">1</td> - - <td align="center">0</td> - - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">4</td> - - <td align="center">1</td> - - <td align="center">0</td> - - <td align="center">0</td></tr> -<tr valign="top"> <td align="center">3</td> - - <td align="center">0</td> - - <td align="center">1</td> - - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">2</td> - - <td align="center">0</td> - - <td align="center">1</td> - - <td align="center">0</td></tr> -<tr valign="top"> <td align="center">1</td> - - <td align="center">0</td> - - <td align="center">0</td> - - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">0</td> - - <td align="center">0</td> - - <td align="center">0</td> - - <td align="center">0</td></tr> -</table></blockquote> - -<p> -Transparency affects the output in the following way. A source or texture -pixel is considered transparent if its value is all 1s (for instance, 1 for -bitmaps, <tt>0xffffff</tt> for 24-bit RGB pixmaps) <b><em>and</em></b> the -corresponding transparency bit is set in the command. For each pixel, the -result of the Boolean operation is written into the destination iff neither -the source nor the texture pixel is transparent. (Note that the HP -RasterOp specification, on which this is based, specifies that if the -source and texture are both all 1s and the command specifies transparent -source and opaque texture, the result <b><em>should</em></b> be written in - the output. We think this is an error in the documentation.) </p> - -<h4><a name="Images"></a>Images</h4> - -<p> -Similar to the high-level interface for fill and stroke graphics, a high-level -interface exists for bitmap images. The procedures in this part of the -interface are optional.</p> - -<p> -Bitmap images come in a variety of types, corresponding closely (but not -precisely) to the PostScript ImageTypes. The generic or common part of all -bitmap images is defined by:</p> - -<blockquote> -<pre>typedef struct { - const gx_image_type_t *type; - gs_matrix ImageMatrix; -} gs_image_common_t;</pre> -</blockquote> - -<p> -Bitmap images that supply data (all image types except -<code>image_type_from_device</code> (2)) are defined by:</p> - -<blockquote> -<pre>#define gs_image_max_components 5 -typedef struct { - << gs_image_common_t >> - int Width; - int Height; - int BitsPerComponent; - float Decode[gs_image_max_components * 2]; - bool Interpolate; -} gs_data_image_t;</pre> -</blockquote> - -<p> -Images that supply pixel (as opposed to mask) data are defined by:</p> - -<blockquote> -<pre>typedef enum { - /* Single plane, chunky pixels. */ - gs_image_format_chunky = 0, - /* num_components planes, chunky components. */ - gs_image_format_component_planar = 1, - /* BitsPerComponent * num_components planes, 1 bit per plane */ - gs_image_format_bit_planar = 2 -} gs_image_format_t; -typedef struct { - << gs_data_image_t >> - const gs_color_space *ColorSpace; - bool CombineWithColor; -} gs_pixel_image_t;</pre> -</blockquote> - -<p> -Ordinary PostScript Level 1 or Level 2 (<code>ImageType</code> 1) images -are defined by:</p> - -<blockquote> -<pre>typedef enum { - /* No alpha. */ - gs_image_alpha_none = 0, - /* Alpha precedes color components. */ - gs_image_alpha_first, - /* Alpha follows color components. */ - gs_image_alpha_last -} gs_image_alpha_t; -typedef struct { - << gs_pixel_image_t >> - bool ImageMask; - bool adjust; - gs_image_alpha_t Alpha; -} gs_image1_t; -typedef gs_image1_t gs_image_t;</pre> -</blockquote> - -<p> -Of course, standard PostScript images don't have an alpha component. For -more details, consult the source code in <a -href="../base/gsiparam.h">gsiparam.h</a> and <code>gsiparm*.h</code>, -which define parameters for an image.</p> - -<p> -The <code>begin[_typed_]image</code> driver procedures create image -enumeration structures. The common part of these structures consists of:</p> - -<blockquote> -<pre>typedef struct gx_image_enum_common_s { - const gx_image_type_t *image_type; - const gx_image_enum_procs_t *procs; - gx_device *dev; - gs_id id; - int num_planes; - int plane_depths[gs_image_max_planes]; /* [num_planes] */ - int plane_widths[gs_image_max_planes] /* [num_planes] */ -} gx_image_enum_common_t;</pre> -</blockquote> - -<p> -where <code>procs</code> consists of:</p> - -<blockquote> -<pre>typedef struct gx_image_enum_procs_s { - - /* - * Pass the next batch of data for processing. - */ -#define image_enum_proc_plane_data(proc)\ - int proc(gx_device *dev,\ - gx_image_enum_common_t *info, const gx_image_plane_t *planes,\ - int height) - - image_enum_proc_plane_data((*plane_data)); - - /* - * End processing an image, freeing the enumerator. - */ -#define image_enum_proc_end_image(proc)\ - int proc(gx_device *dev,\ - gx_image_enum_common_t *info, bool draw_last) - - image_enum_proc_end_image((*end_image)); - - /* - * Flush any intermediate buffers to the target device. - * We need this for situations where two images interact - * (currently, only the mask and the data of ImageType 3). - * This procedure is optional (may be 0). - */ -#define image_enum_proc_flush(proc)\ - int proc(gx_image_enum_common_t *info) - - image_enum_proc_flush((*flush)); - -} gx_image_enum_procs_t;</pre> -</blockquote> - -<p> In other words, <code>begin[_typed]_image</code> sets up an -enumeration structure that contains the procedures that will process the -image data, together with all variables needed to maintain the state of the -process. Since this is somewhat tricky to get right, if you plan to create -one of your own you should probably read an existing implementation of -<code>begin[_typed]_image</code>, such as the one in <a -href="../base/gdevbbox.c">gdevbbox.c</a>.</p> - -<p> -The data passed at each call of <code>image_plane_data</code> consists of -one or more planes, as appropriate for the type of image. -<code>begin[_typed]_image</code> must initialize the -<code>plane_depths</code> array in the enumeration structure with the -depths (bits per element) of the planes. The array of -<code>gx_image_plane_t</code> structures passed to each call of -<code>image_plane_data</code> then defines where the data are stored, as -follows:</p> - -<blockquote> -<pre>typedef struct gx_image_plane_s { - const byte *data; - int data_x; - uint raster; -} gx_image_plane_t;</pre> -</blockquote> - -<dl> -<dt><code>int (*begin_typed_image)(gx_device *dev, -const gs_imager_state *pis, const gs_matrix *pmat, -const gs_image_common_t *pim, gs_int_rect *prect, -const gx_drawing_color *pdcolor, -const gx_clip_path *pcpath, gs_memory_t *memory, -gx_image_enum_common_t **pinfo)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Begin the transmission of an image. Zero or more calls of the - <code>image_plane_data</code> function supplied in the returned image - enumerator will follow, and then a call of -<code>end_image</code>. The parameters of <code>begin_typed_image</code> -are as follows: - -<blockquote><table> -<tr valign="top"><td><code>pis</code></td> - - <td>pointer to an imager state. The only relevant elements of the - imager state are the CTM (coordinate transformation matrix), - the logical operation (<code>RasterOp</code> or - transparency), and the color rendering information. For - mask images, if <code>pmat</code> is not NULL and the color is pure, - <code>pis</code> may be NULL.</td></tr> -<tr valign="top"> <td><code>pmat</code></td> - - <td>pointer to a <code>gs_matrix</code> structure that - defines the image transformation matrix. If <code>pis</code> is non-NULL, - and <code>pmat</code> is NULL, then the <code>ctm</code> from <code>pis</code> - should be used.</td></tr> -<tr valign="top"> <td><code>pim</code></td> - - <td>pointer to the <code>gs_image_t</code> structure that - defines the image parameters</td></tr> -<tr valign="top"> <td><code>prect</code></td> - - <td>if not <code>NULL</code>, defines a subrectangle of the - image; only the data for this subrectangle will be passed to - <code>image_plane_data</code>, and only this subrectangle should - be drawn</td></tr> -<tr valign="top"> <td><code>pdcolor</code></td> - - <td>defines a drawing color, only needed for masks or if - <code>CombineWithColor</code> is true</td></tr> -<tr valign="top"> <td><code>pcpath</code></td> - - <td>if not <code>NULL</code>, defines an optional clipping path</td></tr> -<tr valign="top"> <td><code>memory</code></td> - - <td>defines the allocator to be used for allocating bookkeeping - information</td></tr> -<tr valign="top"> <td><code>pinfo</code></td> - - <td>the implementation should return a pointer to its state - structure here</td></tr> -</table></blockquote> - -<p> -<code>begin_typed_image</code> is expected to allocate a structure for its -bookkeeping needs, using the allocator defined by the memory parameter, and -return it in <code>*pinfo</code>. <code>begin_typed_image</code> should not assume that -the structures in <code>*pim</code>, <code>*prect</code>, or -<code>*pdcolor</code> will survive the call on -<code>begin_typed_image</code> (except for the color space in -<code>*pim->ColorSpace</code>): it should copy any necessary parts of -them into its own bookkeeping structure. It may, however, assume that -<code>*pis</code>, <code>*pcpath</code>, and of course -<code>*memory</code> will live at least until <code>end_image</code> -is called.</p> - -<p> -<code>begin_typed_image</code> returns 0 normally, or 1 if the image does not -need any data. In the latter case, <code>begin_typed_image</code> does not -allocate an enumeration structure.</p> -</dd> -</dl> - -<p> -The format of the image (how pixels are represented) is given by -<code>pim->format</code>.</p> - -<p> -The actual transmission of data uses the procedures in the enumeration -structure, not driver procedures, since the handling of the data usually -depends on the image type and parameters rather than the device. These -procedures are specified as follows.</p> - -<dl> -<dt><code>int (*image_plane_data)(gx_device *dev, -gx_image_enum_common_t *info, -const gx_image_plane_t *planes, int height)</code></dt> -<dd>This call provides more of the image source data: specifically, -<code>height</code> rows, with <code>Width</code> pixels supplied for -each row. - -<p> -The data for each row are packed big-endian within each byte, as for -<code>copy_color</code>. The <code>data_x</code> (starting X position -within the row) and <code>raster</code> (number of bytes per row) are -specified separately for each plane, and may include some padding at the -beginning or end of each row. Note that for non-mask images, the input data -may be in any color space and may have any number of bits per component (1, -2, 4, 8, 12); currently mask images always have 1 bit per component, but in -the future, they might allow multiple bits of alpha. Note also that each -call of <code>image_plane_data</code> passes complete pixels: for example, for -a chunky image with 24 bits per pixel, each call of -<code>image_plane_data</code> passes 3N bytes of data (specifically, -3 × Width × height).</p> - -<p> -The interpretation of planes depends on the <code>format</code> member of -the <code>gs_image[_common]_t</code> structure:</p> - -<ul> -<li>If the format is <code>gs_image_format_chunky</code>, -<code>planes[0].data</code> points to data in "chunky" format, in which -the components follow each other (for instance, RGBRGBRGB....)</li> - -<li>If the format is <code>gs_image_format_component_planar</code>, -<code>planes[0 .. N-1].data</code> point to data for the -<b><em>N</em></b> components (for example, <b><em>N</em></b>=3 for RGB -data); each plane contains samples for a single component, for instance, -RR..., GG..., BB.... Note that the planes are divided by component, not by -bit: for example, for 24-bit RGB data, <b><em>N</em></b>=3, with 8-bit -values in each plane of data.</li> - -<li>If the format is <code>gs_image_format_bit_planar</code>, -<code>planes[0 .. N*B-1].data</code> point to data for the -<b><em>N</em></b> components of <b><em>B</em></b> bits each (for example, -<b><em>N</em></b>=3 and <b><em>B</em></b>=4 for RGB data with 4 bits per -component); each plane contains samples for a single bit, for instance, R0 -R1 R2 R3 G0 G1 G2 G3 B0 B1 B2 B3. Note that the most significant bit of -each plane comes first.</li> -</ul> - -<p> -If, as a result of this call, <code>image_plane_data</code> has been called with all -the data for the (sub-)image, it returns 1; otherwise, it returns 0 or an -error code as usual.</p> - -<p> -<code>image_plane_data</code>, unlike most other procedures that take bitmaps as -arguments, does not require the data to be aligned in any way.</p> - -<p> -Note that for some image types, different planes may have different -numbers of bits per pixel, as defined in the <code>plane_depths</code> array.</p> -</dd> -</dl> - -<dl> -<dt><code>int (*end_image)(gx_device *dev, void *info, -bool draw_last)</code></dt> -<dd>Finish processing an image, either because all data have been supplied -or because the caller has decided to abandon this image. -<code>end_image</code> may be called at any time after -<code>begin_typed_image</code>. It should free the info structure and any -subsidiary structures. If <code>draw_last</code> is true, it should -finish drawing any buffered lines of the image.</dd> -</dl> - -<h5><a name="Images_notes"></a>Notes</h5> - -<p> -While there will almost never be more than one image enumeration in -progress -- that is, after a <code>begin_typed_image</code>, -<code>end_image</code> will almost always be called before the next -<code>begin_typed_image</code> -- driver code should not rely on this -property; in particular, it should store all information regarding the -image in the info structure, not in the driver structure.</p> - -<p> -Note that if <code>begin_typed_image</code> saves its parameters in -the info structure, it can decide on each call whether to use its own -algorithms or to use the default implementation. (It may need to call -<code>gx_default_begin</code>/<code>end_image</code> partway -through.) [A later revision of this document may include an example here.]</p> - -<h4><a name="Text"></a>Text</h4> - -<p> -The third high-level interface handles text. As for images, the interface -is based on creating an enumerator which then may execute the operation in -multiple steps. As for the other high-level interfaces, the procedures are -optional.</p> - -<dl> -<dt><code>int (*text_begin)(gx_device *dev, -gs_imager_state *pis, const gs_text_params_t *text, -gs_font *font, -const gx_clip_path *pcpath, -gs_text_enum_t **ppte)</code> <b><em>[OPTIONAL]</em></b></dt> - -<dd><p></p> -Begin processing text, by creating a state structure and storing it in -<code>*ppte</code>. The parameters of <code>text_begin</code> are as -follows:</dd> -</dl> - -<blockquote><table> -<tr valign="top"> <td><code>dev</code></td> - - <td>The usual pointer to the device.</td></tr> -<tr valign="top"> <td><code>pis</code></td> - - <td>A pointer to an imager state. All elements may be relevant, - depending on how the text is rendered. </td></tr> -<tr valign="top"> <td><code>text</code></td> - - <td>A pointer to the structure that defines the text operation - and parameters. See <a href="../base/gstext.h">gstext.h</a> for details.</td></tr> -<tr valign="top"> <td><code>font</code></td> - - <td>Defines the font for drawing.</td></tr> -<tr valign="top"> <td><code>pcpath</code></td> - - <td>If not <code>NULL</code>, defines an optional clipping path. - Only relevant if the text operation includes - <code>TEXT_DO_DRAW</code>.</td></tr> -<tr valign="top"> <td><code>ppte</code></td> - - <td>The implementation should return a pointer to its state - structure here.</td></tr> -</table></blockquote> - -<p> -<code>text_begin</code> must allocate a structure for its bookkeeping -needs, using the allocator used by the graphics state, -and return it in <code>*ppte</code>. <code>text_begin</code> may -assume that the structures passed as parameters will survive until text -processing is complete.</p> - -<p> -If the text operation includes <code>TEXT_DO...PATH</code> then the -character outline will be appended to the current path in the -<code>pgs</code>. The current point of that path indicates where -drawing should occur and will be updated by the string width -(unless the text operation includes <code>TEXT_DO_NONE</code>).</p> - -<p>If the text operation includes <code>TEXT_DO_DRAW</code> then -the text color will be taken from the current colour in the graphics -state. (Otherwise no colour is required).</p> - -<p>The bookkeeping information will be allocated using the memory -allocator from the graphics state.</p> - -<p> -Clients should not call the driver <code>text_begin</code> procedure -directly. Instead, they should call <code>gx_device_text_begin</code>, -which takes the same parameters and also initializes certain common elements -of the text enumeration structure, or <code>gs_text_begin</code>, which -takes many of the parameters from a graphics state structure. For details, -see <a href="../base/gstext.h">gstext.h</a>.</p> - -<p> -The actual processing of text uses the procedures in the enumeration -structure, not driver procedures, since the handling of the text may depend -on the font and parameters rather than the device. Text processing may also -require the client to take action between characters, either because the -client requested it (<code>TEXT_INTERVENE</code> in the operation) or -because rendering a character requires suspending text processing to call an -external package such as the PostScript interpreter. (It is a deliberate -design decision to handle this by returning to the client, rather than -calling out of the text renderer, in order to avoid potentially unknown -stack requirements.) Specifically, the client must call the following -procedures, which in turn call the procedures in the text enumerator.</p> - -<dl> -<dt><code>int gs_text_process(gs_text_enum_t *pte)</code></dt> -<dd><p></p>Continue processing text. This procedure may return 0 or a negative -error code as usual, or one of the following values (see -<a href="../base/gstext.h">gstext.h</a> for details). - -<blockquote><table> -<tr valign="top"> <td><code>TEXT_PROCESS_RENDER</code></td> - <td>The client must cause the current character to be rendered. - This currently only is used for PostScript Type 0-4 fonts - and their CID-keyed relatives.</td></tr> -<tr valign="top"> <td><code>TEXT_PROCESS_INTERVENE</code></td> - <td>The client has asked to intervene between characters. - This is used for <code>cshow</code> and <code>kshow</code>.</td></tr> -</table></blockquote> -</dd> -</dl> - -<dl> -<dt><code>int gs_text_release(gs_gstate * pgs, gs_text_enum_t *pte, -client_name_t cname)</code></dt><dd><p></p>Finish processing text and release -all associated structures. Clients must call this procedure after -<code>gs_text_process</code> returns 0 or an error, and may call it at -any time.</dd> -</dl> - -<p> -There are numerous other procedures that clients may call during text -processing. See <a href="../base/gstext.h">gstext.h</a> for details.</p> - -<h5><a name="Text_notes"></a>Notes</h5> - -<p> -Note that unlike many other optional procedures, the default implementation -of <code>text_begin</code> cannot simply return: like the default -implementation of <code>begin[_typed]_image</code>, it must create and -return an enumerator. Furthermore, the implementation of the -<code>process</code> procedure (in the enumerator structure, called by -<code>gs_text_process</code>) cannot simply return without doing -anything, even if it doesn't want to draw anything on the output. See the -comments in <a href="../base/gxtext.h">gxtext.h</a> for details.</p> - -<h4><a name="Unicode"></a>Unicode support for high level (vector) devices</h4> - -<p>Implementing a new high level (also known as vector) device, one may need to translate <code>Postscript</code> -character codes into <code>Unicode</code>. This can be done pretty simply.</p> - -<p>For translating a <code>Postscript</code> text you need to inplement the device -virtual function <code>text_begin</code>. It should create a new instance of -<code>gs_text_enum_t</code> in the heap (let its pointer be <code>pte</code>), -and assign a special function to <code>gs_text_enum_t::procs.process</code>. -The function will receive <code>pte</code>. It should take the top level font from -<code>pte->orig_font</code>, -and iterate with <code>font->procs.next_char_glyph(pte, ..., &glyph)</code>. -The last argument receives a <code>gs_glyph</code> value, which encodes a -<code>Postscript</code> character name or CID (and also stores it into -<code>pte->returned.current_glyph</code>). -Then obtain the current subfont with <code>gs_text_current_font(pte)</code> -(it can differ from the font) -and call <code>subfont->procs.decode_glyph(subfont, glyph)</code>. -The return value will be an <code>Unicode</code> code, or <code>GS_NO_CHAR</code> -if the glyph can't be translated to Unicode.</p> - -<h3><a name="Reading_bits_back"></a>Reading bits back</h3> - -<dl> -<dt><code>int (*get_bits_rectangle)(gx_device *dev, -const gs_int_rect *prect, gs_get_bits_params_t *params)</code> <b><em>[OPTIONAL]</em></b></dt> - -<dd> -Read a rectangle of bits back from the device. The <code>params</code> -structure consists of:<p></p> - -<table> -<tr valign="top"> <td><code>options</code></td> - - <td>the allowable formats for returning the data</td></tr> -<tr valign="top"> <td><code>data[32]</code></td> - - <td>pointers to the returned data</td></tr> -<tr valign="top"> <td><code>x_offset</code></td> - - <td>the X offset of the first returned pixel in data</td></tr> -<tr valign="top"> <td><code>raster</code></td> - - <td>the distance between scan lines in the returned data</td></tr> -</table> - -<p> -<code>options</code> is a bit mask specifying what formats the client is -willing to accept. (If the client has more flexibility, the implementation -may be able to return the data more efficiently, by avoiding representation -conversions.) The options are divided into groups.</p> - -</dd> -</dl> - -<blockquote> -<dl> -<dt><b><em>alignment</em></b></dt> -<dd>Specifies whether the returned data must be aligned in the normal -manner for bitmaps, or whether unaligned data are acceptable.</dd> - -<dt><b><em>pointer or copy</em></b></dt> -<dd>Specifies whether the data may be copied into storage provided by the -client and/or returned as pointers to existing storage. (Note that if -copying is not allowed, it is much more likely that the implementation will -return an error, since this requires that the client accept the data in the -implementation's internal format.)</dd> - -<dt><b><em>X offset</em></b></dt> -<dd>Specifies whether the returned data must have a specific X offset -(usually zero, but possibly other values to avoid skew at some later stage -of processing) or whether it may have any X offset (which may avoid skew in -the <code>get_bits_rectangle</code> operation itself).</dd> - -<dt><b><em>raster</em></b></dt> -<dd>Specifies whether the raster (distance between returned scan lines) -must have its standard value, must have some other specific value, or may -have any value. The standard value for the raster is the device width -padded out to the alignment modulus when using pointers, or the minimum -raster to accommodate the X offset + width when copying (padded out to the -alignment modulus if standard alignment is required).</dd> - -<dt><b><em>format</em></b></dt> -<dd>Specifies whether the data are returned in chunky (all components of a -single pixel together), component-planar (each component has its own scan -lines), or bit-planar (each bit has its own scan lines) format.</dd> - -<dt><b><em>color space</em></b></dt> -<dd>Specifies whether the data are returned as native device pixels, or in -a standard color space. Currently the only supported standard space is -RGB.</dd> - -<dt><b><em>standard component depth</em></b></dt> -<dd>Specifies the number of bits per component if the data are returned in -the standard color space. (Native device pixels use -<code>dev</code>-><code>color_info.depth</code> bits per pixel.)</dd> - -<dt><b><em>alpha</em></b></dt> -<dd>Specifies whether alpha channel information should be returned as the -first component, the last component, or not at all. Note that for devices -that have no alpha capability, the returned alpha values will be all 1s. -</dd></dl> - -</blockquote> - -<p> -The client may set more than one option in each of the above groups; the -implementation will choose one of the selected options in each group to -determine the actual form of the returned data, and will update -<code>params[].options</code> to indicate the form. The returned -<code>params[].options</code> will normally have only one option set per -group.</p> - -<p> -For further details on <code>params</code>, see <a -href="../base/gxgetbit.h">gxgetbit.h</a>. For further details on -<code>options</code>, see <a href="../base/gxbitfmt.h">gxbitfmt.h</a>.</p> - -<p> -Define w = <code>prect</code>->q.x - <code>prect</code>->p.x, h -= <code>prect</code>->q.y - <code>prect</code>->p.y. If the -bits cannot be read back (for example, from a printer), return -<code>gs_error_unknownerror</code>; if raster bytes is not enough space -to hold <code>offset_x</code> + w pixels, or if the source rectangle -goes outside the device dimensions (p.x < 0 || p.y < 0 || q.x > -<code>dev</code>->width || q.y > <code>dev</code>->height), -return <code>gs_error_rangecheck</code>; if any regions could not be -read, return <code>gs_error_ioerror</code> if unpainted is -<code>NULL</code>, otherwise the number of rectangles (see below); -otherwise return 0.</p> - -<p> -The caller supplies a buffer of <code>raster</code> × h -bytes starting at <code>data[0]</code> for the returned data in chunky -format, or <b><em>N</em></b> buffers of -<code>raster</code> × h bytes starting at -<code>data[0]</code> through -<code>data[</code><b><em>N-1</em></b><code>]</code> in planar format -where <b><em>N</em></b> is the number of components or bits. The contents -of the bits beyond the last valid bit in each scan line (as defined by w) -are unpredictable. data need not be aligned in any way. If -<code>x_offset</code> is non-zero, the bits before the first valid bit -in each scan line are undefined. If the implementation returns pointers to -the data, it stores them into <code>data[0]</code> or -<code>data[</code><b><em>0..N-1</em></b><code>]</code>.</p> - -<h3><a name="Parameters"></a>Parameters</h3> - -<p> -Devices may have an open-ended set of parameters, which are simply pairs -consisting of a name and a value. The value may be of various types: -integer (int or long), boolean, float, string, name, <code>NULL</code>, -array of integer, array of float, or arrays or dictionaries of mixed types. -For example, the <code>Name</code> of a device is a string; the -<code>Margins</code> of a device is an array of two floats. See -<a href="../base/gsparam.h">gsparam.h</a> for more details.</p> - -<p> -If a device has parameters other than the ones applicable to all devices -(or, in the case of printer devices, all printer devices), it must provide -<code>get_params</code> and <code>put_params</code> procedures. If -your device has parameters beyond those of a straightforward display or -printer, we strongly advise using the <code>_get_params</code> and -<code>_put_params</code> procedures in an existing device (for example, -<a href="../devices/gdevcdj.c">gdevcdj.c</a> or <a -href="../devices/gdevbit.c">gdevbit.c</a>) as a model for your own code.</p> - -<dl> -<dt><code>int (*get_params)(gx_device *dev, -gs_param_list *plist)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Read the parameters of the device into the parameter list at -<code>plist</code>, using the <code>param_write_*</code> -macros or procedures defined in <a href="../base/gsparam.h">gsparam.h</a>.</dd> -</dl> - -<dl> -<dt><code>int (*get_hardware_params)(gx_device *dev, -gs_param_list *plist)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Read the hardware-related parameters of the device into the parameter -list at plist. These are any parameters whose values are under control of -external forces rather than the program -- for example, front panel -switches, paper jam or tray empty sensors, etc. If a parameter involves -significant delay or hardware action, the driver should only determine the -value of the parameter if it is "requested" by the -<code>gs_param_list</code> [<code>param_requested</code>(plist, -<code>key_name</code>)]. This function may cause the asynchronous -rendering pipeline (if enabled) to be drained, so it should be used -sparingly.</dd> -</dl> - -<dl> -<dt><code>int (*put_params)(gx_device *dev, -gs_param_list *plist)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Set the parameters of the device from the parameter list at -<code>plist</code>, using the <code>param_read_</code>* -macros/procedures defined in <a href="../base/gsparam.h">gsparam.h</a>. All -<code>put_params</code> procedures must use a "two-phase commit" -algorithm; see <a href="../base/gsparam.h">gsparam.h</a> for details.</dd> -</dl> - -<h4><a name="Default_CRD_parameters"></a>Default color rendering -dictionary (CRD) parameters</h4> - -<p> -Drivers that want to provide one or more default CIE color rendering -dictionaries (CRDs) can do so through <code>get_params</code>. To do -this, they create the CRD in the usual way (normally using the -<code>gs_cie_render1_build</code> and <code>_initialize</code> -procedures defined in <a href="../base/gscrd.h">gscrd.h</a>), and then write -it as a parameter using <code>param_write_cie_render1</code> defined in -<a href="../base/gscrdp.h">gscrdp.h</a>. However, the TransformPQR procedure -requires special handling. If the CRD uses a TransformPQR procedure -different from the default (identity), the driver must do the following:</p> - -<ul> -<li>The TransformPQR element of the CRD must include a -<code>proc_name</code>, and optionally <code>proc_data</code>. The -<code>proc_name</code> is an arbitrary name chosen by the driver to -designate the particular TransformPQR function. It must not be the same as -any device parameter name; we strongly suggest it include the device name, -for instance, "<code>bitTPQRDefault</code>".</li> - -<li>For each such named TransformPQR procedure, the driver's -<code>get_param</code> procedure must provide a parameter of the same -name. The parameter value must be a string whose bytes are the actual -procedure address.</li> -</ul> - -<p> -For a complete example, see the <code>bit_get_params</code> procedure in -<a href="../devices/gdevbit.c">gdevbit.c</a>. Note that it is essential that -the driver return the CRD or the procedure address only if specifically -requested (<code>param_requested(...)</code> > 0); otherwise, errors -will occur.</p> - -<h4><a name="Device parameters affecting interpretation"></a>Device parameters affecting interpretation</h4> - -<p> -Some parameters have been defined for high level (vector) device drivers which affect -the operation of the interpreter. These are documented here so that other devices -requiring the same behaviour can use these parameters.</p> - -<blockquote><dl> -<dt><b><em>/HighLevelDevice</em></b></dt> -<dd>True if the device is a high level (vector) device. Currently this controls haltone emission -during setpagedevice. Normally setpagdevice resets the halftone to a default value, which is -unfortunate for high-level devices such as ps2write and pdfwrite, as they are unable to tell -that this is caused by setpagdevice rather than a halftone set by the input file. In order to prevent -spurious default halftones being embedded in the output, if /HighLevelDevice is present and -true in the device paramters, then the default halftone will not be set during setpagedevice. -Also prevents interpolation of imagemasks during PDF interpretation. -</dd> - -<dt><b><em>/AllowIncrementalCFF</em></b></dt> -<dd>Pdfwrite relies on font processing occuring in a particular order, which -may not happen if CFF fonts are downloaded incrementally. Defining this -parameter to true will prevent incremental CFF downloading (may raise an error -during processing). -</dd> - -<dt><b><em>/AllowPSRepeatFuncs</em></b></dt> -<dd>Pdfwrite emits functions as type 4, and as a result can't convert PostScript -functions using the repeat operator into PDF functions. Defining this parameter -as true will cause such functions to raise an error during processing. -</dd> - -<dt><b><em>/IsDistiller</em></b></dt> -<dd>Defining this parameter as true will result in the operators relating to -'distillerparams' being defined (setdistillerparams/currentdistillerparams). -Some PostScript files behave differently if these operators are present (e.g. -rotating the page) so this parameter may be true even if the device is not -strictly a Distiller. For example ps2write defines this parameter to be -true. -</dd> - -<dt><b><em>/PreserveSMask</em></b></dt> -<dd>If this parameter is true then the PDF interpreter will not convert SMask -(soft mask, ie transparent) images into opaque images. This should be set to true -for devices which can handle transparency (e.g. pdfwrite) -</dd> - -<dt><b><em>/PreserveTrMode</em></b></dt> -<dd>If this parameter is true then the PDF interpreter will not handle Text -Rendering modes by degenerating into a sequence of text operations, but will -instead set the Tr mode, and emit the text once. This value should be true -for devices which can handle PDF text rendering modes directly. -</dd> - -<dt><b><em>/WantsToUnicode</em></b></dt> -<dd>In general, Unicode values are not of interest to rendering devices, but -for high level (aka vector) devices, they can be extremely valuable. If this parameter is -defined as true then ToUnicode CMaps and GlyphName2Unicode tables will be -processed and stored. -</dd> -</dl></blockquote> - -<h3><a name="Page_devices"></a>Page devices</h3> - -<dl> -<dt><code>gx_device *(*get_page_device)(gx_device *dev)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>According to the Adobe specifications, some devices are "page devices" -and some are not. This procedure returns <code>NULL</code> if the -device is not a page device, or the device itself if it is a page device. -In the case of forwarding devices, <code>get_page_device</code> returns -the underlying page device (or <code>NULL</code> if the underlying -device is not a page device).</dd> -</dl> - -<h3><a name="Miscellaneous"></a>Miscellaneous</h3> - -<dl> -<dt><code>int (*get_band)(gx_device *dev, int y, -int *band_start)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>If the device is a band device, this procedure stores in -<code>*band_start</code> the scan line (device Y coordinate) of the band -that includes the given Y coordinate, and returns the number of scan lines -in the band. If the device is not a band device, this procedure returns 0. -The latter is the default implementation.</dd> -</dl> - -<dl> -<dt><code>void (*get_clipping_box)(gx_device *dev, -gs_fixed_rect *pbox)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Stores in <code>*pbox</code> a rectangle that defines the device's -clipping region. For all but a few specialized devices, this is -<em>((0,0),(width,height))</em>.</dd> -</dl> - -<h3><a name="DevSpecOp"></a>Device Specific Operations</h3> - -<p>In order to enable the provision of operations that make sense only -to a small range of devices/callers, we provide an extensible function. The -operation to perform is specified by an integer, taken from an enumeration -in <a href="../base/gxdevsop.h">gxdevsop.h</a>.</p> - -<p>A typical user of this function might make a call to detect whether -a device works in a particular way (such as whether it has a particular -color mapping) to enable an optimisation elsewhere. Sometimes it may be used -to detect a particular piece of functionality (such as whether -<code>copy_plane</code> is supported); in other cases it may be used both -to detect the presence of other functionality and to perform functions as -well (such as with the pdf specific pattern management calls - moved -here from their own dedicated device function).</p> - -<p>This function is designed to be easy to chain through multiple levels of -device without each intermediate device needing to know about the full -range of operations it may be asked to perform.</p> - -<dl> -<dt><code>int (*dev_spec_op)(gx_device *dev, int dso, -void *data, int size)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Perform device specific operation <code>dso</code>. Returns -<code>gs_error_undefined</code> for an unknown (or unsupported operation), -other negative values for errors, and (<code>dso</code> specific) -non-negative values to indicate success. For details of the meanings of -<code>dso</code>, <code>data</code> and <code>size</code>, see -<a href="../base/gxdevsop.h">gxdevsop.h</a>.</dd> -</dl> - -<hr> - -<h2><a name="Tray"></a>Tray selection</h2> - -<!-- Note for documentation maintainers: tray selection overlaps --> -<!-- significantly across the device interface and the PostScript --> -<!-- language implementation of setpagedevice, while the rest of --> -<!-- Drivers.htm focusses on lanugage-independent interfaces. Likely --> -<!-- the documentation should be refactored a bit so that this section --> -<!-- has a comfortable home. --> - -<p>The logic for selecting input trays, and modifying other parameters -based on tray selection, can be complex and subtle, largely thanks to -the requirement to be compatible with the PostScript language -setpagedevice mechanism. This section will describe recipes for -several common scenarios for tray selection, with special attention to -the how the overall task factors into configuration options, generic -logic provided by the PostScript language (or not, if the device is -used with other PDL's), and implementation of the put_param / -get_param device functions within the device.</p> - -<p>In general, tray selection is determined primarily through the -setpagedevice operator, which is part of the PostScript runtime. -Ghostscript attempts to be as compatible as is reasonable with the -PostScript standard, so for more details, see the description in the -<a -href="http://partners.adobe.com/public/developer/ps/index_specs.html">PostScript -language specifications</a>, including the "supplements", which tend -to have more detail about setpagedevice behavior than the PLRM book itself.</p> - -<p>The first step is to set up an /InputAttributes dictionary matching -the trays and so on available in the device. The standard Ghostscript -initialization files set up a large InputAttributes dictionary with -many "known" page sizes (the full list is in -<code>gs_statd.ps</code>, under .setpagesize). It's possible to -edit this list in the Ghostscript source, of course, but most of the -time it is better to execute a snippet of PostScript code after the -default initialization but before sending any actual jobs.</p> - -<p>Simply setting a new /InputAttributes dictionary with setpagedevice -will not work, because the the language specification for -setpagedevice demands a "merging" behavior - paper tray keys present -in the old dictionary will be preserved even if the key is not present -in the new /InputAttributes dictionary. Here is a sample invocation -that clears out all existing keys, and installs three new ones: a US letter -page size for trays 0 and 1, and 11x17 for tray 1. Note that you must add at -least one valid entry into the /InputAttributes dictionary; if all are -<code>null</code>, then the setpagedevice will fail with a -/configurationerror.</p> - -<blockquote><code> -<< /InputAttributes<br> - currentpagedevice /InputAttributes get<br> - dup { pop 1 index exch null put } forall<br> -<br> - dup 0 << /PageSize [612 792] >> put<br> - dup 1 << /PageSize [612 792] >> put<br> - dup 2 << /PageSize [792 1224] >> put<br> ->> setpagedevice<br> -</code></blockquote> - -<p>After this code runs, then requesting a letter page size (612x792 -points) from setpagedevice will select tray 0, and requesting an 11x17 -size will select tray 2. To explicitly request tray 1, run:</p> - -<blockquote><code> -<< /PageSize [612 792] /MediaPosition 1 >> setpagedevice -</code></blockquote> - -<p>At this point, the chosen tray is sent to the device as the -(nonstandard) %MediaSource device parameter. Devices with switchable -trays should implement this device parameter in the -<code>put_params</code> procedure. Unlike the usual protocol for -device parameters, it is not necessary for devices to also implement -<code>get_params</code> querying of this paramter; it is -effectively a write-only communication from the language to the -device. Currently, among the devices that ship with Ghostscript, only -PCL (gdevdjet.c) and PCL/XL (gdevpx.c) implement this parameter, but -that list may well grow over time.</p> - -<p>If the device has dynamic configuration of trays, etc., then the -easiest way to get that information into the tray selection logic is -to send a setpagedevice request (if using the standard API, then using -gsapi_run_string_continue) to update the /InputAttributes dictionary -immediately before beginning a job.</p> - -<h3><a name="LeadingEdge"></a>Tray rotation and the LeadingEdge parameter</h3> - -<p>Large, sophisticated printers often have multiple trays supporting -both short-edge and long-edge feed. For example, if the paper path is -11 inches wide, then 11x17 pages must always print short-edge, but -letter size pages print with higher throughput if fed from long-edge -trays. Generally, the device will expect the rasterized bitmap image -to be rotated with respect to the page, so that it's always the same -orientation with respect to the paper feed direction.</p> - -<p>The simplest way to achieve this behavior is to call -<code>gx_device_request_leadingedge</code> to request a LeadingEdge -value -<code>LeadingEdge</code> field in the device structure based on the -%MediaSource tray selection index and knowledge of the device's -trays. The default put_params implementation will then handle this -request (it's done this way to preserve the transactional semantics of -put_params; it needs the new value, but the changes can't actually be -made until all params succeed). For example, if tray 0 is long-edge, -while trays 1 and 2 are short-edge, the following code outline should -select the appropriate rotation:</p> - -<blockquote><code> -my_put_params(gx_device *pdev, gs_param_list *plist) {<br> - my_device *dev = (my_device *)pdev;<br> - int MediaSource = dev->myMediaSource;<br> -<br> - code = param_read_int(plist, "%MediaSource", &MediaSource);<br> -<br> - switch (MediaSource) {<br> - case 0:<br> - gx_device_req_leadingedge(dev, 1);<br> - break;<br> - case 1:<br> - case 2:<br> - gx_device_req_leadingedge(dev, 0);<br> - break;<br> - }<br> - ...call default put_params, which makes the change...<br> -<br> - dev->myMediaSource = MediaSource;<br> - return 0;<br> -} -</code></blockquote> - -<p>Ghostscript also supports explicit rotation of the page through -setting the /LeadingEdge parameter with setpagedevice. The above code -snippet will simply override this request. To give manual setting -through setpagedevice priority, don't change the LeadingEdge field in -the device if its LEADINGEDGE_SET_MASK bit is set. In other words, -simply enclose the above <tt>switch</tt> statement inside an <code>if -(!(dev->LeadingEdge & LEADINGEDGE_SET_MASK) { ... }</code> statement.</p> - -<!-- Note for doc maintainers: the following is much more of a --> -<!-- discussion of the PS language than a device interface issue, but --> -<!-- it is essential info for people implementing this stuff. --> - -<h3><a name="LeadingPage"></a>Interaction between LeadingEdge and PageSize</h3> - -<p>As of LanguageLevel 3, PostScript now has two mechanisms for rotating -the imaging of the page: the LeadingEdge parameter described in detail -above, and the automatic rotation as enabled by the /PageSize page -device parameter (described in detail in Table 6.2 of the PLRM3). -Briefly, the PageSize autorotation handles the case where the page -size requested in setpagedevice matches the <i>swapped</i> size of the -paper source (as set in the InputAttributesDictionary). This mechanism -can be, and has been, used to implement long-edge feed, but has -several disadvantages. Among other things, it's overly tied to the PostScript -language, while the device code above will work with other -languages. Also, it only specifies one direction of rotation (90 -degrees counterclockwise). Thus, given the choice, LeadingEdge is to -be preferred.</p> - -<p>If PageSize is used, the following things are different:</p> - -<ul> -<li>The PageSize array in InputAttributes is swapped, so it is [long -short].</li> -<li>The .MediaSize device parameter is similarly swapped.</li> -<li>The initial matrix established by the device through the -<code>get_initial_matrix</code> procedure is the same as for the -non-rotated case.</li> -<li>The CTM rotation is done in the setpagedevice implementation.</li> -</ul> - -<!-- Why oh why does it all have to be so complicated? --> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Fonts.htm b/doc/Fonts.htm deleted file mode 100644 index ea32a808..00000000 --- a/doc/Fonts.htm +++ /dev/null @@ -1,348 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Fonts and Font Facilities Supplied with Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Fonts and Font Facilities Supplied with Ghostscript</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#About">About Ghostscript fonts</a></li> - <li><a href="#Free_fonts">Ghostscript's free fonts</a></li> - <li><a href="#Get_fonts">How Ghostscript gets fonts when it runs</a></li> - <li><a href="#Platform_fonts">Platform fonts</a></li> - <li><a href="#Add_fonts">Adding your own fonts</a></li> - <li> - <ul> - <li><a href="#Convert_BDF">Converting BDF fonts</a></li> - </ul> - </li> - <li><a href="#For_developers">For developers only</a></li> - <li><a href="#Use_gs_fonts_with_X">Using Ghostscript fonts on X Windows displays</a></li> - <li> - <ul> - <li><a href="#Using_xset">Using <code>xset</code></a></li> - <li><a href="#Font_permanent_installation">Permanent installation</a></li> - <li> - <ul> - <li><a href="#Configure_xfs">Configuring the <code>xfs</code> font server</a></li> - <li><a href="#Configure_Xfree86">Xfree86 display servers</a></li> - </ul> - </li> - </ul> - </li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="About"></a>About Ghostscript fonts</h2> - -<p> -Ghostscript is distributed with two kinds of files related to fonts:</p> - -<ul> -<li>the fonts themselves in individual files, and</li> -<li>a file "<code>Fontmap</code>" that defines for -Ghostscript which file represents which font.</li> -</ul> - -<p> -Additionally, the file <code>cidfmap</code> can be used -to create substitutes for CIDFonts referenced by name in Postscript and PDF jobs. -See the section on <a href="Use.htm#CIDFontSubstitution">CID Font Substitution</a> -for details. NOTE: care must be exercised since poor or incorrect output may result -from inappropriate CIDFont substitution. We therefore <strong>strongly</strong> recommend -embedding CIDFonts in your Postscript and PDF files if at all possible.</p> - -<p> -The "base 35" fonts required for Postscript (and "base 14" required for PDF) -are Postscript Type 1 font files.</p> -<p><a name="Fontmap"></a> -When Ghostscript needs a font, it must have some way to know where to look -for it: that's the purpose of the <code>Fontmap</code> file, which -associates the names of <em>fonts</em> such as <code>/Times-Roman</code> -with the names of font <em>files</em>, such as -<code>n021003l.pfb</code>. <code>Fontmap</code> can also create -aliases for font names, so that for instance, -<code>/NimbusNo9L-Regu</code> means the same font as -<code>/Times-Roman</code>.</p> -<p>Where a mapping in <code>Fontmap</code> maps a font name to a path/file, -the directory containing the font file is automatically added to the <code>permit -file read</code> list. For example: -<br> -<code>/Arial (/usr/share/fonts/truetype/msttcorefonts/arial.ttf) ;</code> -<br> -will result in the path <code>/usr/share/fonts/truetype/msttcorefonts/</code> being -added to the <code>permit file read</code> list. This is done on the basis that font files -are often grouped in common directories, and rather than risk the file permissions lists -being swamped with (potentially) hundreds of individual files, it makes sense to add the -directories. -<p><b>NOTE:</b> Fontmap is processed (and the paths added to the file permissions list) during -initialisation of the Postscript interpreter, so any attempt by a Postscript job to change the -font map cannot influence the file permissions list. -<hr> - -<h2><a name="Free_fonts"></a>Ghostscript's free fonts</h2> -<ul> -<li>35 commercial-quality Type 1 basic PostScript fonts -- Times, -Helvetica, Courier, Symbol, etc. -- contributed by URW++ Design and -Development Incorporated, of Hamburg, Germany -(<a href="http://www.urwpp.de/">http://www.urwpp.de/</a>). Fontmap names -them all.</li> -</ul> -<hr> -<h2><a name="Get_fonts"></a>How Ghostscript gets fonts when it runs</h2> - -<p> -Fonts occupy about 50KB each, so Ghostscript doesn't load them all -automatically when it runs. Instead, as part of normal initialization -Ghostscript runs a file <code>gs_fonts.ps</code>, which arranges to load -fonts on demand using information from the font map. To preload all of the -known fonts, invoke the procedure</p> - -<blockquote><code> -loadallfonts -</code></blockquote> - -<p> -The file <code>lib/prfont.ps</code> contains code to print a sample page of -a font. Load this program by including it in the <code>gs</code> -command line or by invoking</p> - -<blockquote><code> -(prfont.ps) run -</code></blockquote> - -<p> -Then to produce a sampler of a particular font XYZ, invoke</p> - -<blockquote><code> -/XYZ DoFont -</code></blockquote> - -<p>For example,</p> - -<blockquote><code> -/Times-Roman DoFont -</code></blockquote> - -<p> -For more information about how Ghostscript loads fonts during execution, -see <a href="Use.htm#Font_lookup">here</a>.</p> - -<hr> - -<h2><a name="Add_fonts"></a>Adding your own fonts</h2> - -<p> -Ghostscript can use any Type 0, 1, 3, 4, or 42 font acceptable to -other PostScript language interpreters or to ATM, including MultiMaster -fonts. Ghostscript can also use TrueType font files.</p> - -<p> -To add fonts of your own, you must edit Fontmap to include at the end an -entry for your new font; the format for entries is documented -in Fontmap itself. Since later entries in Fontmap override earlier -entries, a font you add at the end supersedes any corresponding fonts supplied -with Ghostscript and defined earlier in the file. To ensure correct output, -it is vital that entries for the "base 35" fonts remain intact -in the Fontmap file.</p> - -<p> -In the PC world, Type 1 fonts are customarily given names ending in -<code>.PFA</code> or <code>.PFB</code>. Ghostscript can use these -directly: you just need to make the entry in Fontmap. If you want to use -with Ghostscript a commercial Type 1 font (such as fonts obtained in -conjunction with Adobe Type Manager), please read carefully the license that -accompanies the font to satisfy yourself that you may do so legally; we take -no responsibility for any possible violations of such licenses. The same -applies to TrueType fonts.</p> - -<h3><a name="Convert_BDF"></a>Converting BDF fonts (- deprecated!)</h3> - -<p> -Ghostscript provides a way to construct a (low-quality) Type 1 font from a -bitmap font in the BDF format popular in the Unix world. The shell script -<code>bdftops</code> (Unix) or the command file -<code>bdftops.bat</code> (DOS) converts a BDF file to a -scalable outline using <code>bdftops.ps</code> . Run the -shell command</p> - -<blockquote><code> -bdftops BDF_filename [AFM_file1_name ...] gsf_filename fontname<br> UniqueID [XUID] [encodingname] -</code></blockquote> - -<p> -The arguments have these meanings:</p> -<blockquote><table> -<tr valign="top"> <td><code>BDF_filename</code></td> - - <td>Input bitmap file in BDF format</td> - - <td> </td></tr> -<tr valign="top"> <td><code>AFM_file1_name</code></td> - - <td>AFM files giving metrics</td> - - <td>(Optional)</td></tr> -<tr valign="top"> <td><code>gsf_filename</code></td> - - <td>Output file</td> - - <td> </td></tr> -<tr valign="top"> <td><code>fontname</code></td> - - <td>Name of the font</td> - - <td> </td></tr> -<tr valign="top"> <td><code>UniqueID</code></td> - - <td>UniqueID (<a href="#Unique_IDs">as described below</a>)</td> - - <td> </td></tr> -<tr valign="top"> <td><code>XUID</code></td> - - <td>XUID, in the form <code>n1.n2.n3...</code> (<a href="#Unique_IDs">as described below</a>)</td> - - <td>(Optional)</td></tr> -<tr valign="top"> <td><code>encodingname</code></td> - - <td>"StandardEncoding" (the default), "ISOLatin1Encoding",<br>"SymbolEncoding", "DingbatsEncoding"</td> - - <td>(Optional)</td></tr> -</table></blockquote> - -<p> -For instance</p> - -<blockquote><code> -bdftops pzdr.bdf ZapfDingbats.afm pzdr.gsf ZapfDingbats 4100000 1000000.1.41 -</code></blockquote> - -<p> -Then make an entry in Fontmap for the <code>.gsf</code> -file (<code>pzdr.gsf</code> in the example) as -<a href="#Add_fonts">described above</a>.</p> - -<hr> - -<h2><a name="For_developers"></a>For developers only</h2> - -<p> -The rest of this document is very unlikely to be of value to ordinary -users.</p> - -<h3><a name="Font_contents"></a>Contents of fonts</h3> - -<p> -As noted above, Ghostscript accepts fonts in the same formats as PostScript -interpreters. Type 0, 1, and 3 fonts are documented in the PostScript -Language Reference Manual (Second Edition); detailed documentation for Type -1 fonts appears in a separate Adobe book. Type 2 (compressed format) fonts -are documented in separate Adobe publications. Type 4 fonts are not -documented anywhere; they are essentially Type 1 fonts with a BuildChar or -BuildGlyph procedure. Types 9, 10, and 11 (CIDFontType 0, 1, and 2) and -Type 32 (downloaded bitmap) fonts are documented in Adobe supplements. -Type 42 (encapsulated TrueType) fonts are documented in an Adobe -supplement; the TrueType format is documented in publications available -from Apple and Microsoft. Ghostscript does not support Type 14 (Chameleon) -fonts, which use a proprietary Adobe format.</p> - -<h3><a name="Unique_IDs"></a>Font names and unique IDs</h3> - -<p> -If you create your own fonts and will use them only within your own -organization, you should use <code>UniqueID</code> values between -4000000 and 4999999.</p> - -<p> -If you plan to distribute fonts, ask Adobe to assign you some UniqueIDs and -also an <code>XUID</code> for your organization. Contact</p> - -<blockquote><address> -Unique ID Coordinator<br> -Adobe Developers Association<br> -Adobe Systems, Inc.<br> -345 Park Avenue<br> -San Jose, CA 95110-2704<br> -+1-408-536-9000 telephone (ADA)<br> -+1-408-536-6883 fax<br> -<a href="mailto:fontdev-person@adobe.com">fontdev-person@adobe.com</a><br> -</address></blockquote> - -<p> -The XUID is a Level 2 PostScript feature that serves the same function as -the UniqueID, but is not limited to a single 24-bit integer. The -<code>bdftops</code> program creates XUIDs of the form -"<code>[-X- 0 -U-]</code>" where "<code>-X-</code>" is the -organization XUID and "<code>-U-</code>" is the UniqueID. (Aladdin -Enterprises' organization XUID, which appears in a few places in various -font-related files distributed with Ghostscript, is 107; do not use this for -your own fonts that you distribute.)</p> - -<hr> - -<h2><a name="Use_gs_fonts_with_X"></a>Using Ghostscript fonts on X Windows displays</h2> - -<p> The "Xfonts" feature is no longer supported.</p> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/GPDL.htm b/doc/GPDL.htm deleted file mode 100644 index 42dae96a..00000000 --- a/doc/GPDL.htm +++ /dev/null @@ -1,566 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>The GhostPDL Interpreter Framework</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>The GhostPDL Interpreter Framework</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#What_Is_This">What is the GhostPDL Interpreter Framework?</a></li> - <li><a href="#API">The API</a></li> - <li> - <ul> - <li><a href="#run">The run_string functions</a></li> - <li><a href="#string_vs_file">String vs File functions</a></li> - </ul> - </li> - <li><a href="#executable">The GPDL executable</a></li> - <li><a href="#different_switches">Differences in switches from Ghostscript</a></li> - <li><a href="#languages">Supported languages</a></li> - <li> - <ul> - <li><a href="#PJL">PJL</a></li> - <li><a href="#PCL">PCL</a></li> - <li><a href="#PCLXL">PCLXL</a></li> - <li><a href="#XPS">XPS</a></li> - <li><a href="#POSTSCRIPT">POSTSCRIPT</a></li> - <li><a href="#URF">URF</a></li> - <li><a href="#JPG">JPG</a></li> - <li><a href="#PWG">PWG</a></li> - <li><a href="#TIFF">TIFF</a></li> - <li><a href="#JBIG2">JBIG2</a></li> - <li><a href="#JP2K">JP2K</a></li> - <li><a href="#PNG">PNG</a></li> - </ul> - </li> - <li><a href="#new_language">Adding a new language</a></li> - <li> - <ul> - <li><a href="proc_characteristics">proc_characteristics</a></li> - <li><a href="proc_allocate_interp_instance">proc_allocate_interp_instance</a></li> - <li><a href="proc_get_device_memory">proc_get_device_memory</a></li> - <li><a href="proc_set_param">proc_set_param</a></li> - <li><a href="proc_add_path">proc_add_path</a></li> - <li><a href="proc_post_args_init">proc_post_args_init</a></li> - <li><a href="proc_init_job">proc_init_job</a></li> - <li><a href="proc_run_prefix_commands">proc_run_prefix_commands</a></li> - <li><a href="proc_process_file">proc_process_file</a></li> - <li><a href="proc_process_begin">proc_process_begin</a></li> - <li><a href="proc_process">proc_process</a></li> - <li><a href="proc_process_end">proc_process_end</a></li> - <li><a href="proc_flush_to_eoj">proc_flush_to_eoj</a></li> - <li><a href="proc_process_eof">proc_process_eof</a></li> - <li><a href="proc_report_errors">proc_report_errors</a></li> - <li><a href="proc_dnit_job">proc_dnit_job</a></li> - <li><a href="proc_deallocate_interp_instance">proc_deallocate_interp_instance</a></li> - </ul> - </li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript overview</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - - -<h2><a name="What_Is_This"></a>What is the GhostPDL Interpreter Framework?</h2> - -<p> -The GhostPDL interpreter framework (henceforth, just GhostPDL) is -a framework into which multiple interpreters can be fitted, together -with a set of interpreters for different input "languages".</p> -<p>The intent is that a build of GPDL will behave as much as possible -like a build of Ghostscript, but should be able to transparently -cope with as many different input formats as it has interpreters built -into it.</p> -<p>It can be built as a dynamic link library -(DLL) on Microsoft Windows, as a shared object on the -Linux, Unix and MacOS X platforms. With some changes, it could be built -as a static library.</p> -<p>The reason we dub it a "Framework" is that it is -designed to be modular, and to readily allow new interpreters to be -swapped in and out to extend and customise its capabilities.</p> - -<p>Jobs must be separated by <code>UEL</code> (Universal End of Language) -code sequences (or PJL fragments, which implicitly start with a -<code>UEL</code> marker).</p> - -<h2><a name="API"></a>The API</h2> - -<p>The API for GPDL (found in <a href="../pcl/pl/plapi.h">plapi.h</a>) -is deliberately designed to be nearly identical -to that for Ghostscript itself (found in <a href="../psi/iapi.h">iapi.h</a>). -Details of Ghostscript's API can be -found <a href="API.htm">here</a>, and we refer you to that. Only -differences from that API will be documented here. In particular -the differences in the handling of switches within the -<code>gsapi_init_with_args</code> are documented -<a href="#different_switches">here</a>.</p> -<p>Our intent is that existing users of the Ghostscript API should be -able to drop a GPDL DLL in as a replacement with little to no code -changes.</p> - -<h3><a name="run"></a>The run_string APIs</h3> - -<p>The <code>run_string</code> APIs have parameters for -<code>int user_errors</code> and <code>int *error_code</code>. -Within Ghostscript, these allow a caller to bypass the language's -standard error handling, and to trap errors externally. -This makes no sense within a printer implementation (and, in -particular, no sense for a postscript interpreter running -jobs within a JobServer loop as GPDL does). Thus these -parameters are kept for ABI compatibility, but are largely -ignored within the GPDL implementation of gsapi. -For sanity, pass 0 for <code>user_errors</code>, and expect -<code>*error_code</code> to be set to 0 on exit.</p> - -<h3><a name="string_vs_file"></a>String vs File functions</h3> - -<p>Some file types, such as Postscript and PCL, are designed to be -'streamable'; that is to say that the files can be fed in and -consumed as they are interpreted. Other file types, such as PDF or -XPS require the whole file to be available so that the interpreters -can seek back and forth within it to extract the data they require.</p> - -<p>Traditionally, Ghostscript has relied upon the caller knowing -which type of data is which; streamable data can be fed in to the -system using the <code>gsapi_run_string</code> APIs, and complete files -of data can be fed in using <code>gsapi_run_file</code> or -<code>gsapi_init_with_args</code> APIs. Streamable data contained -with a file is simple to deal with, as it's trivial for an interpreter -to read bytes from a file, but doing random access on a stream is -much harder.</p> - -<p>In systems where data is being streamed in, but it is required -to be available for random access, the entire stream must be buffered -for presentation to the language interpreters. With Ghostscript, -the responsibility for doing this fell to the caller. Unfortunately, -this means that the caller also has to be responsible for scanning -the incoming data to spot when it is in a format that requires -buffering. With the explosion of formats that GPDL supports this -quickly becomes unpalatable.</p> - -<p>While the caller is still free to do such buffering of data -itself, GPDL will do it automatically if required. If a language -spots that data being fed to it via the <code>gsapi_run_string</code> -APIs is in a format that requires buffering, the entire string of -data will be automatically collected together, and then be -represented internally to the <code>gsapi_run_file</code> API.</p> - -<p>The current implementation buffers the data in memory. Alternative -implementations could use a backing store if such a thing were -available. For server based applications the use of memory is not -likely to be a problem (assuming reasonably sized input files at least). -For printer integrations, it's entirely possible that no backing -store will be available, so RAM may be the only option. Integrators -may wish to place a limit on the size of files that can be buffered -in this way.</p> - -<h2><a name="executable"></a>The GPDL executable</h2> - -<p> -The GPDL executable is a small executable that loads the DLL/shared object, -and implements, pretty much, the interface described in the -<a href="Use.htm">usage documentation</a> for Ghostscript, but capable of -reading any of the configured languages. This executable provides all -the interaction with the windowing system, including image windows.</p> - -<p>Areas where the GPDL executable differs from the Ghostscript -executable are described <a href="#different_switches">below</a>. These -are primarily to do with (slightly) esoteric requirements when -running Postscript in an interactive environment. Whereas Ghostscript -is a generic Postscript interpreter, GPDL is unashamedly targeted -as a print processor.</p> - -<p> -The GPDL framework's library name and characteristics differ -for each platform:</p> - -<ul> -<li>The Win32 DLL <code>gpdldll32.dll</code> -can be used by multiple programs simultaneously, but only once -within each process.</li> - -<li>The Linux shared object <code>libgs.so</code> -can be used by multiple programs simultaneously.</li> -</ul> -<p> -The source for the executable is in <code>plw</code>*.* (Windows) -and <code>plx</code>*.* (Linux/Unix). -See these source files for examples of how to use the DLL.</p> - -<p> -At this stage, GhostPDL does not support multiple instances -of the interpreter within a single process.</p> - -<h2><a name="different_switches"></a>Differences in switches from Ghostscript</h3> - -<p>The <code>gsapi_init_with_args</code> API entrypoint takes a -set of arguments, which can include various switches. We document -the differences between Ghostscript's handling of switches and -GhostPDLs here. The GhostPDL executable directly maps parameters -given on the command-line into this list, so this list of differences -applies both to API calls and uses of the executable.</p> - -<p>GhostPDL does not support the <code>-_</code>, <code>-+</code>, -<code>-@</code>, <code>-B</code>, <code>-F</code>, <code>-M</code>, -<code>-N</code>, <code>-P</code>, <code>-u</code>, and <code>-X</code> -switches that Ghostscript does. - -<p>GhostPDL supports a few switches that the Ghostscript executable -does not.</p> - -<ul> - <li><b><code>-E #</code>:</b> Sets the "error reporting mode" -for PCL/PXL.</li> - <li><b><code>-H #x#x#x#</code>:</b> Sets the hardware margins to the -given left/bottom/right/top values (in points).</li> - <li><b><code>-j <string></code>:</b> Passes the string to the - PJL level. The string is split on ';'.</li> - <li><b><code>-J</code>:</b> Same as <code>-j</code>.</li> - <li><b><code>-l {RTL,PCL5E,PCL5C}</code>:</b> Sets the - "personality" of the PCL/PXL interpreter.</li> - <li><b><code>-L <language></code>:</b> Sets the language - to be used. Run with <code>-L</code> and no string to see a list - of languages supported in your build.</li> - <li><b><code>-m #x#</code>:</b> Sets the margin values to the - left/bottom values (in points).</li> -</ul> - -<h2><a name="languages"></a>Supported languages</h2> - -<p>The following is a (possibly non-exhaustive) list of languages -for which implementations exist for GhostPDL. We use the term -"language" to include both full page description languages -(such as PCL, Postscript and XPS), and handlers for simpler formats -(such as JPEG, PNG and TIFF).</p> -<p>It is inherent in the design that new handlers can be included, -and unwanted formats can be dropped from any given build/integration.</p> - -<h3><a name="PJL"></a>PJL</h3> -<p>PJL is special, in that it is the central language implementation -to which we return between all jobs. As such it always appears first -in the list, and must be present in all builds.</p> -<h3><a name="PCL"></a>PCL</h3> -<p>The PCL language implementation supports PCL5C/PXL5E and HPGL/2 -with RTL.</p> -<h3><a name="PCLXL"></a>PCLXL</h3> -<p>The PCLXL language implementation supports PCLXL.</p> -<h3><a name="XPS"></a>XPS</h3> -<p>The XPS language implementation supports the XML Paper Specification -format, as used in modern Windows systems printing pipelines.</p> -<h3><a name="POSTSCRIPT"></a>POSTSCRIPT</h3> -<p>The POSTSCRIPT language implementation is the Ghostscript - Postscript interpreter, as described in the accompanying - documentation.</p> -<h3><a name="URF"></a>URF</h3> -<p>Currently available to commercial customers only, the URF language -implementation implements support for the URF file format, as used -by Apple Airprint.</p> -<h3><a name="JPG"></a>JPG</h3> -<p>The JPG language implementation supports JPEG files -(in both JFIF and EXIF formats).</p> -<h3><a name="PWG"></a>PWG</h3> -<p>The PWG language implementation supports PWG -(Printer Working Group) format files.</p> -<h3><a name="TIFF"></a>TIFF</h3> -<p>The TIFF language implementation supports TIFF format files in -a variety of compression formats, depending on the exact configuration -of libtiff used in the build.</p> -<h3><a name="JBIG2"></a>JBIG2</h3> -<p>The JBIG2 language implementation supports JBIG2 format images.</p> -<h3><a name="JP2K"></a>JP2K</h3> -<p>The JP2K language implementation supports JPEG2000 and JPX format -images.</p> -<h3><a name="PNG"></a>PNG</h3> -<p>The PNG language implementation supports PNG format images.</p> - -<h2><a name="new_language"></a>Adding a new language</h2> - -<p>Each language implementation in the system appears as an instance -of a <code>pl_interp_implementation_t</code> structure. - -<pre> -typedef struct pl_interp_implementation_s -{ - /* Procedure vector */ - pl_interp_proc_characteristics_t proc_characteristics; - pl_interp_proc_allocate_interp_instance_t proc_allocate_interp_instance; - pl_interp_proc_get_device_memory_t proc_get_device_memory; - pl_interp_proc_set_param_t proc_set_param; - pl_interp_proc_add_path_t proc_add_path; - pl_interp_proc_post_args_init_t proc_post_args_init; - pl_interp_proc_init_job_t proc_init_job; - pl_interp_proc_run_prefix_commands_t proc_run_prefix_commands; - pl_interp_proc_process_file_t proc_process_file; - pl_interp_proc_process_begin_t proc_process_begin; - pl_interp_proc_process_t proc_process; - pl_interp_proc_process_end_t proc_process_end; - pl_interp_proc_flush_to_eoj_t proc_flush_to_eoj; - pl_interp_proc_process_eof_t proc_process_eof; - pl_interp_proc_report_errors_t proc_report_errors; - pl_interp_proc_dnit_job_t proc_dnit_job; - pl_interp_proc_deallocate_interp_instance_t - proc_deallocate_interp_instance; - void *interp_client_data; -} pl_interp_implementation_t; -</pre> - -<p>This structure consists of series of function pointers, each -of which performs some portion of the processing required to handle -detection of language type and processing of data. These function -pointers are described in detail below.</p> -<p>In addition, the <code>interp_client_data</code> field is -used to hold the running state of a given interpreter.</p> - -<p>All the languages to be supported in the build are listed -in the <code>pdl_implementations</code> array in -<a href="../pcl/pl/plimpl.c">plimpl.c</a>. To add a new implementation -the name of the appropriate <code>pl_interp_implementation_t</code> -should be added here.</a> - -<p>The existing range of language implementations may prove useful -as references when implementing new ones. They can be found as -<code>gpdl/*top.c</code>. In particular, -<code><a href="../gpdl/pngtop.c">pngtop.c</a></code> is a simple -implementation of a well-defined, relatively simple file format -(PNG), based upon a well-known and well-documented library (libpng), -so is probably a good place to start.</p> - -<h3><a name="proc_characteristics"></a>proc_characteristics</h3> -<pre> -typedef const pl_interp_characteristics_t - *(*pl_interp_proc_characteristics_t) (const pl_interp_implementation_t *); -</pre> -<p>This entrypoint is called to request details of the characteristics -of the language. This must be implemented in all instances.</p> -<p>This returns a pointer to a <code>pl_interp_characteristics_t</code> - structure:</p> -<pre> -typedef struct pl_interp_characteristics_s -{ - const char *language; /* generic language should correspond with - HP documented PJL name */ - int (*auto_sense)(const char *string, int length); /* routine used to detect language - returns a score: 0 is definitely not, 100 is definitely yes. */ - const char *manufacturer; /* manuf str */ - const char *version; /* version str */ - const char *build_date; /* build date str */ -} pl_interp_characteristics_t; -</pre> -<p>The <code>language</code> entry contains a simple NULL terminated - string that names the interpreter. Similarly, the <code>manufacturer</code>, - <code>version</code>, and <code>build_date</code> fields are for - informational purposes only.</p> -<p>The <code>auto_sense</code> function is called with a prefix of data - from each new source. Each language is passed the data in turn, and - "scores;" according to how sure it is the file is that format.</p> -<p>For many file formats this means looking for known in the first -few bytes (such as PNG or TIFF looking for their signature bytes). For -others, such as XPS, the best that can be done is to spot that it's a - zip file. For still others, such as PCL, heuristics have to be used.</p> -<p>A 'definite' match is returned as 100, a definite rejection as 0, with -intermediate values used appropriately.</p> -<h3><a name="proc_allocate_interp_instance"></a>proc_allocate_interp_instance</h3> -<pre> -typedef int (*pl_interp_proc_allocate_interp_instance_t) - (pl_interp_implementation_t *, - gs_memory_t *); -</pre> -<p>On startup, the GPDL library calls around all the languages -via this function, getting them to allocate themselves an instance. - What this means will vary between languages, but typically it involves - allocating a state structure, and storing the pointer to that in the - <code>interp_client_data</code> pointer of the - <code>pl_interp_implementation_t *</code>. Part of this state structure - will typically be a <code>gstate</code> to use to drive the graphics - library.</p> -<h3><a name="proc_get_device_memory"></a>proc_get_device_memory</h3> -<pre> -typedef gs_memory_t *(*pl_interp_proc_get_device_memory_t) - (pl_interp_implementation_t *); -</pre> -<p>On shutdown, the GPDL library calls around all the languages -via this function, getting them to release their resources and -deallocate any memory.</p> -<h3><a name="proc_set_param"></a>proc_set_param</h3> -<pre> -typedef int (*pl_interp_proc_set_param_t) (pl_interp_implementation_t *, - pl_set_param_type, - const char *, - const void *); -</pre> -<p>Some languages (particularly Postscript) can have their behaviour -changed by the use of parameters. This function provides a generic -method for the GPDL library to pass parameters into a language. Each -language is free to ignore the parameters that do not apply to it. For -most languages, this can safely be passed as <code>NULL</code>.</p> -<h3><a name="proc_add_path"></a>proc_add_path</h3> -<pre> -typedef int (*pl_interp_proc_add_path_t) (pl_interp_implementation_t *, - const char *); -</pre> -<p>Some languages (particularly Postscript) have the ability to - open files from the local storage. These files can be found - in a variety of different locations within the local storage. - As such this call allows the GPDL library to add paths to - the current list of locations that will be searched. For - most languages, this can safely be passed as <code>NULL</code>.</p> -<h3><a name="proc_post_args_init"></a>proc_post_args_init</h3> -<pre> -typedef int (*pl_interp_proc_post_args_init_t) (pl_interp_implementation_t *); -</pre> -<p></p> -<h3><a name="proc_init_job"></a>proc_init_job</h3> -<pre> -typedef int (*pl_interp_proc_init_job_t) (pl_interp_implementation_t *, - gx_device *); -</pre> -<p>Once the GPDL library has identified which language should be used -for an incoming job, it will call this entrypoint to initialise the -language for the job. What this means will vary between languages, -but at the very minimum the job will need to take note of the device -to be used.</p> -<h3><a name="proc_run_prefix_commands"></a>proc_run_prefix_commands</h3> -<pre> -typedef int (*pl_interp_proc_run_prefix_commands_t) - (pl_interp_implementation_t *, - const char *prefix); -</pre> -<p>The GPDL library (and executable) allow language commands to be -sent in the argument parameters using the <code>-c</code> switch. These -are collected into a buffer, and forwarded to a language to be run -as part of the same job as any following file.</p> -<p>Currently, only the Postscript language handler implements this -function, all others should pass <code>NULL</code>.</p> -<h3><a name="proc_process_file"></a>proc_process_file</h3> -<pre> -typedef int (*pl_interp_proc_process_file_t) (pl_interp_implementation_t *, - const char *); -</pre> -<p>If the GPDL library is given a filename to process, and this function -is non-NULL, it will call this to run the file. For file formats such as -PDF (which need to be buffered so they can be read out of order), this -can avoid the need to feed in all the data via <code>proc_process</code>, -buffer it somewhere, and then process it at the end.</p> -<p>For many languages this can be <code>NULL</code>.</p> -<h3><a name="proc_process_begin"></a>proc_process_begin</h3> -<pre> -typedef int (*pl_interp_proc_process_begin_t) (pl_interp_implementation_t *); -</pre> -<p>Once the GPDL library has data to process (that it cannot process -with <code>proc_process_file</code>, it will call this function to -setup the transfer of data.</p> -<h3><a name="proc_process"></a>proc_process</h3> -<pre> -typedef int (*pl_interp_proc_process_t) (pl_interp_implementation_t *, - stream_cursor_read *); -</pre> -<p>After the GPDL library has called <code>proc_process_begin</code> -this function may be called multiple times to actually transfer -the data in. The implementation is expected to consume as many bytes -as it can (but not necessarily all of them) before returning with -an updated read pointer. If this function cannot advance without more -data, it should return with <code>gs_error_NeedInput</code>.</p> -<h3><a name="proc_process_end"></a>proc_process_end</h3> -<pre> -typedef int (*pl_interp_proc_process_end_t) (pl_interp_implementation_t *); -</pre> -<p>After the GPDL library has called <code>proc_process_begin</code> -(and possibly made a number of calls to <code>proc_process</code>) it -will call <code>proc_process_end</code> to signify the end of the -data. This does not necessarily signal the end of the job.</p> -<h3><a name="proc_flush_to_eoj"></a>proc_flush_to_eoj</h3> -<pre> -typedef int (*pl_interp_proc_flush_to_eoj_t) (pl_interp_implementation_t *, - stream_cursor_read *); -</pre> -<p>In the event of a problem while processing data, GPDL may seek to -abandon processing of a transfer in progress by calling -<code>proc_flush_to_eoj</code>. If possible, the language should -continue to process data until a reasonable stopping point, or until -<code>UEL</code> is reached.</p> -<h3><a name="proc_process_eof"></a>proc_process_eof</h3> -<pre> -typedef int (*pl_interp_proc_process_eof_t) (pl_interp_implementation_t *); -</pre> -<p>Called when GPDL reaches EOF in processing a job. A language -implementation should assume no more data is forthcoming.</p> -<h3><a name="proc_report_errors"></a>proc_report_errors</h3> -<pre> -typedef int (*pl_interp_proc_report_errors_t) (pl_interp_implementation_t *, - int, - long, - bool); -</pre> -<p>Called after running a job to give the language implementation the -chance to report any errors it may have detected as it ran.</p> -<h3><a name="proc_dnit_job"></a>proc_dnit_job</h3> -<pre> -typedef int (*pl_interp_proc_dnit_job_t) (pl_interp_implementation_t *); -</pre> -<p>Called after a job is complete so that the language implementation -may clean up. The interpreter is kept open so that more jobs can be -fed to it, but no state should be kept from this job to the next.</p> -<h3><a name="proc_deallocate_interp_instance"></a>proc_deallocate_interp_instance</h3> -<pre> -typedef int (*pl_interp_proc_deallocate_interp_instance_t) - (pl_interp_implementation_t *); -</pre> -<p>Called on shutdown of the GPDL library to close down the language -instance and free all the resources.</p> - -<!-- [2.0 end contents] ==================================================== --> -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small></p> - -<p> -This software is provided AS-IS with no warranty, either express or -implied.</p> - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.</p> - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Ghostscript.pdf b/doc/Ghostscript.pdf new file mode 100644 index 00000000..037031ad --- /dev/null +++ b/doc/Ghostscript.pdf @@ -0,0 +1,1882 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 30 0 R /F4 47 0 R /F5 50 0 R /F6 68 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 108 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/Contents 109 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 48 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 40.01575 754.0394 98.34575 766.0394 ] /Subtype /Link /Type /Annot +>> +endobj +7 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 48 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 754.7894 555.2598 766.7894 ] /Subtype /Link /Type /Annot +>> +endobj +8 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 60.01575 736.0394 152.2657 748.0394 ] /Subtype /Link /Type /Annot +>> +endobj +9 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 736.7894 555.2598 748.7894 ] /Subtype /Link /Type /Annot +>> +endobj +10 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 721.8394 0 ] /Rect [ 80.01575 718.0394 130.5857 730.0394 ] /Subtype /Link /Type /Annot +>> +endobj +11 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 721.8394 0 ] /Rect [ 549.6998 718.7894 555.2598 730.7894 ] /Subtype /Link /Type /Annot +>> +endobj +12 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 587.0394 0 ] /Rect [ 80.01575 700.0394 126.6957 712.0394 ] /Subtype /Link /Type /Annot +>> +endobj +13 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 587.0394 0 ] /Rect [ 549.6998 700.7894 555.2598 712.7894 ] /Subtype /Link /Type /Annot +>> +endobj +14 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 410.2394 0 ] /Rect [ 80.01575 682.0394 126.1457 694.0394 ] /Subtype /Link /Type /Annot +>> +endobj +15 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 410.2394 0 ] /Rect [ 549.6998 682.7894 555.2598 694.7894 ] /Subtype /Link /Type /Annot +>> +endobj +16 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 197.4394 0 ] /Rect [ 80.01575 664.0394 126.1457 676.0394 ] /Subtype /Link /Type /Annot +>> +endobj +17 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 197.4394 0 ] /Rect [ 549.6998 664.7894 555.2598 676.7894 ] /Subtype /Link /Type /Annot +>> +endobj +18 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 80.01575 646.0394 126.7057 658.0394 ] /Subtype /Link /Type /Annot +>> +endobj +19 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 646.7894 555.2598 658.7894 ] /Subtype /Link /Type /Annot +>> +endobj +20 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 40.01575 676.2394 0 ] /Rect [ 80.01575 628.0394 179.4857 640.0394 ] /Subtype /Link /Type /Annot +>> +endobj +21 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 40.01575 676.2394 0 ] /Rect [ 549.6998 628.7894 555.2598 640.7894 ] /Subtype /Link /Type /Annot +>> +endobj +22 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 60.01575 610.0394 191.7357 622.0394 ] /Subtype /Link /Type /Annot +>> +endobj +23 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 610.7894 555.2598 622.7894 ] /Subtype /Link /Type /Annot +>> +endobj +24 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 80.01575 592.0394 245.0857 604.0394 ] /Subtype /Link /Type /Annot +>> +endobj +25 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 549.6998 592.7894 555.2598 604.7894 ] /Subtype /Link /Type /Annot +>> +endobj +26 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 617.0394 0 ] /Rect [ 80.01575 574.0394 226.7257 586.0394 ] /Subtype /Link /Type /Annot +>> +endobj +27 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 617.0394 0 ] /Rect [ 549.6998 574.7894 555.2598 586.7894 ] /Subtype /Link /Type /Annot +>> +endobj +28 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 464.2394 0 ] /Rect [ 80.01575 556.0394 200.0657 568.0394 ] /Subtype /Link /Type /Annot +>> +endobj +29 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 464.2394 0 ] /Rect [ 549.6998 556.7894 555.2598 568.7894 ] /Subtype /Link /Type /Annot +>> +endobj +30 0 obj +<< +/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +31 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 383.4394 0 ] /Rect [ 80.01575 538.0394 261.7657 550.0394 ] /Subtype /Link /Type /Annot +>> +endobj +32 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 383.4394 0 ] /Rect [ 549.6998 538.7894 555.2598 550.7894 ] /Subtype /Link /Type /Annot +>> +endobj +33 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 314.6394 0 ] /Rect [ 80.01575 520.0394 187.8357 532.0394 ] /Subtype /Link /Type /Annot +>> +endobj +34 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 314.6394 0 ] /Rect [ 549.6998 520.7894 555.2598 532.7894 ] /Subtype /Link /Type /Annot +>> +endobj +35 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 40.01575 723.0394 0 ] /Rect [ 80.01575 502.0394 232.8457 514.0394 ] /Subtype /Link /Type /Annot +>> +endobj +36 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 40.01575 723.0394 0 ] /Rect [ 549.6998 502.7894 555.2598 514.7894 ] /Subtype /Link /Type /Annot +>> +endobj +37 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 60.01575 484.0394 210.6257 496.0394 ] /Subtype /Link /Type /Annot +>> +endobj +38 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 484.7894 555.2598 496.7894 ] /Subtype /Link /Type /Annot +>> +endobj +39 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 80.01575 466.0394 190.6157 478.0394 ] /Subtype /Link /Type /Annot +>> +endobj +40 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 549.6998 466.7894 555.2598 478.7894 ] /Subtype /Link /Type /Annot +>> +endobj +41 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 671.0394 0 ] /Rect [ 80.01575 448.0394 430.1857 460.0394 ] /Subtype /Link /Type /Annot +>> +endobj +42 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 671.0394 0 ] /Rect [ 549.6998 448.7894 555.2598 460.7894 ] /Subtype /Link /Type /Annot +>> +endobj +43 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 567.4394 0 ] /Rect [ 80.01575 430.0394 205.0457 442.0394 ] /Subtype /Link /Type /Annot +>> +endobj +44 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 567.4394 0 ] /Rect [ 549.6998 430.7894 555.2598 442.7894 ] /Subtype /Link /Type /Annot +>> +endobj +45 0 obj +<< +/Annots [ 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R + 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R + 26 0 R 27 0 R 28 0 R 29 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R + 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R ] /Contents 110 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +46 0 obj +<< +/Contents 111 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +47 0 obj +<< +/BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +48 0 obj +<< +/Contents 112 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +49 0 obj +<< +/Contents 113 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +50 0 obj +<< +/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +51 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 119.4957 615.0394 140.8121 627.0394 ] /Subtype /Link /Type /Annot +>> +endobj +52 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.gnu.org/licenses/agpl-3.0.html) +>> /Border [ 0 0 0 ] /Rect [ 208.4357 231.4394 316.8057 243.4394 ] /Subtype /Link /Type /Annot +>> +endobj +53 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com/licensing/commercial/) +>> /Border [ 0 0 0 ] /Rect [ 353.4957 231.4394 446.2857 243.4394 ] /Subtype /Link /Type /Annot +>> +endobj +54 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 471.8457 231.4394 500.1857 243.4394 ] /Subtype /Link /Type /Annot +>> +endobj +55 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 241.2357 213.4394 261.2457 225.4394 ] /Subtype /Link /Type /Annot +>> +endobj +56 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.gnu.org/licenses/agpl-3.0.html) +>> /Border [ 0 0 0 ] /Rect [ 208.4357 132.6394 316.8057 144.6394 ] /Subtype /Link /Type /Annot +>> +endobj +57 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com/licensing/commercial/) +>> /Border [ 0 0 0 ] /Rect [ 353.4957 132.6394 446.2857 144.6394 ] /Subtype /Link /Type /Annot +>> +endobj +58 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 471.8457 132.6394 500.1857 144.6394 ] /Subtype /Link /Type /Annot +>> +endobj +59 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 343.4657 114.6394 391.9252 126.6394 ] /Subtype /Link /Type /Annot +>> +endobj +60 0 obj +<< +/Annots [ 51 0 R 52 0 R 53 0 R 54 0 R 55 0 R 56 0 R 57 0 R 58 0 R 59 0 R ] /Contents 114 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +61 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.gnu.org/licenses/agpl-3.0.html) +>> /Border [ 0 0 0 ] /Rect [ 208.9957 722.2394 317.3657 734.2394 ] /Subtype /Link /Type /Annot +>> +endobj +62 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com/licensing/commercial/) +>> /Border [ 0 0 0 ] /Rect [ 354.0557 722.2394 446.8457 734.2394 ] /Subtype /Link /Type /Annot +>> +endobj +63 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 472.4057 722.2394 500.7457 734.2394 ] /Subtype /Link /Type /Annot +>> +endobj +64 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 344.0257 704.2394 392.1558 716.2394 ] /Subtype /Link /Type /Annot +>> +endobj +65 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://en.wikipedia.org/wiki/Aladdin_Free_Public_License) +>> /Border [ 0 0 0 ] /Rect [ 142.8457 617.4394 167.8557 629.4394 ] /Subtype /Link /Type /Annot +>> +endobj +66 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 182.2957 575.4394 210.6357 587.4394 ] /Subtype /Link /Type /Annot +>> +endobj +67 0 obj +<< +/Annots [ 61 0 R 62 0 R 63 0 R 64 0 R 65 0 R 66 0 R ] /Contents 115 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +68 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font +>> +endobj +69 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://bugs.ghostscript.com) +>> /Border [ 0 0 0 ] /Rect [ 388.7157 642.0394 489.3006 654.0394 ] /Subtype /Link /Type /Annot +>> +endobj +70 0 obj +<< +/A << +/S /URI /Type /Action /URI (file:///home/cliddell/artifex/ghostpdl-release/doc/COPYING) +>> /Border [ 0 0 0 ] /Rect [ 188.6357 561.2394 302.5657 573.2394 ] /Subtype /Link /Type /Annot +>> +endobj +71 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://ghostscript.com/doc/current/News.htm) +>> /Border [ 0 0 0 ] /Rect [ 63.01575 327.6394 88.01575 339.6394 ] /Subtype /Link /Type /Annot +>> +endobj +72 0 obj +<< +/A << +/S /URI /Type /Action /URI (file:///home/cliddell/artifex/ghostpdl-release/doc/COPYING) +>> /Border [ 0 0 0 ] /Rect [ 40.01575 177.8394 71.13575 189.8394 ] /Subtype /Link /Type /Annot +>> +endobj +73 0 obj +<< +/Annots [ 69 0 R 70 0 R 71 0 R 72 0 R ] /Contents 116 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +74 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/) +>> /Border [ 0 0 0 ] /Rect [ 302.3557 676.2394 396.8157 688.2394 ] /Subtype /Link /Type /Annot +>> +endobj +75 0 obj +<< +/Annots [ 74 0 R ] /Contents 117 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +76 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/) +>> /Border [ 0 0 0 ] /Rect [ 40.01575 687.7894 134.4757 699.7894 ] /Subtype /Link /Type /Annot +>> +endobj +77 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/en/ps/PLRM.pdf) +>> /Border [ 0 0 0 ] /Rect [ 431.8757 619.4394 553.0774 631.4394 ] /Subtype /Link /Type /Annot +>> +endobj +78 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/en/ps/PLRM.pdf) +>> /Border [ 0 0 0 ] /Rect [ 40.01575 607.4394 192.4259 619.4394 ] /Subtype /Link /Type /Annot +>> +endobj +79 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf) +>> /Border [ 0 0 0 ] /Rect [ 212.3057 607.4394 333.2395 619.4394 ] /Subtype /Link /Type /Annot +>> +endobj +80 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/pdf/index_reference.html) +>> /Border [ 0 0 0 ] /Rect [ 335.6057 595.4394 464.5796 607.4394 ] /Subtype /Link /Type /Annot +>> +endobj +81 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/acrobat/sdk/index.html) +>> /Border [ 0 0 0 ] /Rect [ 470.6557 595.4394 555.2598 607.4394 ] /Subtype /Link /Type /Annot +>> +endobj +82 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html) +>> /Border [ 0 0 0 ] /Rect [ 80.03575 583.4394 330.1257 595.4394 ] /Subtype /Link /Type /Annot +>> +endobj +83 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://www.artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 156.1757 478.6394 261.6142 490.6394 ] /Subtype /Link /Type /Annot +>> +endobj +84 0 obj +<< +/Annots [ 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R 81 0 R 82 0 R 83 0 R ] /Contents 118 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +85 0 obj +<< +/Outlines 87 0 R /PageLabels 119 0 R /PageMode /UseNone /Pages 107 0 R /Type /Catalog +>> +endobj +86 0 obj +<< +/Author () /CreationDate (D:20000101000000+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20000101000000+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) + /Subject (\(unspecified\)) /Title () /Trapped /False +>> +endobj +87 0 obj +<< +/Count 23 /First 88 0 R /Last 88 0 R /Type /Outlines +>> +endobj +88 0 obj +<< +/Count 18 /Dest [ 48 0 R /XYZ 40.01575 787.0394 0 ] /First 89 0 R /Last 103 0 R /Parent 87 0 R /Title (Introduction) +>> +endobj +89 0 obj +<< +/Count 6 /Dest [ 60 0 R /XYZ 40.01575 787.0394 0 ] /First 90 0 R /Last 95 0 R /Next 96 0 R /Parent 88 0 R + /Title (What is Ghostscript?) +>> +endobj +90 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 721.8394 0 ] /Next 91 0 R /Parent 89 0 R /Title (Ghostscript) +>> +endobj +91 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 587.0394 0 ] /Next 92 0 R /Parent 89 0 R /Prev 90 0 R /Title (GhostPDF) +>> +endobj +92 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 410.2394 0 ] /Next 93 0 R /Parent 89 0 R /Prev 91 0 R /Title (GhostPDL) +>> +endobj +93 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 197.4394 0 ] /Next 94 0 R /Parent 89 0 R /Prev 92 0 R /Title (GhostPCL) +>> +endobj +94 0 obj +<< +/Dest [ 67 0 R /XYZ 40.01575 787.0394 0 ] /Next 95 0 R /Parent 89 0 R /Prev 93 0 R /Title (GhostXPS) +>> +endobj +95 0 obj +<< +/Dest [ 67 0 R /XYZ 40.01575 676.2394 0 ] /Parent 89 0 R /Prev 94 0 R /Title (URW Font Information) +>> +endobj +96 0 obj +<< +/Count 6 /Dest [ 73 0 R /XYZ 40.01575 787.0394 0 ] /First 97 0 R /Last 102 0 R /Next 103 0 R /Parent 88 0 R + /Prev 89 0 R /Title (Document roadmap by theme) +>> +endobj +97 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 751.8394 0 ] /Next 98 0 R /Parent 96 0 R /Title (What should I read if I\220m a new user?) +>> +endobj +98 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 617.0394 0 ] /Next 99 0 R /Parent 96 0 R /Prev 97 0 R /Title (GPL and commercial Ghostscript) +>> +endobj +99 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 464.2394 0 ] /Next 100 0 R /Parent 96 0 R /Prev 98 0 R /Title (Before building Ghostscript) +>> +endobj +100 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 383.4394 0 ] /Next 101 0 R /Parent 96 0 R /Prev 99 0 R /Title (What should I read if I\220m not a new user?) +>> +endobj +101 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 314.6394 0 ] /Next 102 0 R /Parent 96 0 R /Prev 100 0 R /Title (What if I\220m a developer?) +>> +endobj +102 0 obj +<< +/Dest [ 75 0 R /XYZ 40.01575 723.0394 0 ] /Parent 96 0 R /Prev 101 0 R /Title (What if I\220m writing documentation?) +>> +endobj +103 0 obj +<< +/Count 3 /Dest [ 84 0 R /XYZ 40.01575 787.0394 0 ] /First 104 0 R /Last 106 0 R /Parent 88 0 R /Prev 96 0 R + /Title (Presence on the World Wide Web) +>> +endobj +104 0 obj +<< +/Dest [ 84 0 R /XYZ 40.01575 751.8394 0 ] /Next 105 0 R /Parent 103 0 R /Title (Ghostscript\220s home page) +>> +endobj +105 0 obj +<< +/Dest [ 84 0 R /XYZ 40.01575 671.0394 0 ] /Next 106 0 R /Parent 103 0 R /Prev 104 0 R /Title (Adobe PostScript, Encapsulated PostScript, and PDF reference documentation) +>> +endobj +106 0 obj +<< +/Dest [ 84 0 R /XYZ 40.01575 567.4394 0 ] /Parent 103 0 R /Prev 105 0 R /Title (Other material on the WWW) +>> +endobj +107 0 obj +<< +/Count 11 /Kids [ 4 0 R 5 0 R 45 0 R 46 0 R 48 0 R 49 0 R 60 0 R 67 0 R 73 0 R 75 0 R + 84 0 R ] /Type /Pages +>> +endobj +108 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 404 +>> +stream +Gatn!b>,r/&4Q?mMHN7L_p!Al,YKUQ2m=_*#MP>-&Ufaqa62KYBh=6"6UHWm`P&P&ad@Y=`V":-#NuCP]4><#0EkKV#ZksWbd69*WJ&2BEKDFUa^uI+M_V*5\ShZV/\DtF1a@SM=)i-oE6?^':)o-@K-_pdkkE<*>)("1"t3djFb&%AP%sYq,i]n]`0s1m!MKj"C/">YP":PL*?5M0QKrQS.;#UnY"+D:dF0h'7gQf<J%HQZL@s,)"nd?J,Mesqm8f<S4c-NY'M=K9F,f-o?E@e_"`OT6g=bl&](N_:7c'8!L48/WF`thR\/W9`=V7-thp1/m-th$,r=c:JG(VeTFImk-SJ+G0$9nS5*bHRRid=+<S$0t^50aNI5)G[ulT_h8hpAf>ISg+:!BZOU>l~>endstream +endobj +109 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 92 +>> +stream +GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_H"Zg#ZYSJTP%YGC2U%ZDJ?(_?u0NYeAi<FV8*670]3GC~>endstream +endobj +110 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 920 +>> +stream +GauI7?Z2Df'ZJu*'_a>_<e?;?j_7ouUl&,cC!2`(m"Ku=0EmsaZ>/9G"p/Ya]%djO&g\+oTC]D6\L%G1r?C?9QiLCf0V/gu'`96gAhrlEi5R^))J"%=ZV69rQ\4UEe$;-6YLCbY"]XrG>Jmi,fe>SO=VUSEe<?$33@T:6Padml!k&8)^u^u(YIi3YUp6`7';21UnUptO$<&:FS9\L?LUrFsBfhW-_0"!W\rpb[dQIC,rX\ME$K(ShY:]4%\rCp7Ct-aFp/7b)JN)X*f[R$:pMA9pAp&Q2Zb!ka1q?%;LQpYmBs)!R%J*]!n,$VgDG4f=rGMV/qk@1QE#b&rh<7?_,.5enX.q7DNFdAe/Gb*Z]YcU6"ZaL=gob1RB;(2Aq'Q;PXbbm[n+,.&53e7G+%,V4i]<%K#RuFJg8AB(XsXLP>%JNtc;/#_6SR%?__Bd2e2WKQ$H$E7,GPJjdZ09]R(gfd&PT!]Qsa#CX*[NfI@.o?QQMTl9<"'S(\<XG+FN7ESJTqG^R!h:dBs^R%&,$"^u@<6/!5Y*OH&TuO;nYmF:XJ=Q=VSW>t6U!S!"nGGR;jfPgT[98B!B$1SGBQX`6'(1HQafAp4f^&VMo2KF6aI%7c\r7XGtMg-'U3Kt]>H/@P(0MUSIJ0kh_$KZ5:nPN\Ws\C;Trm+o(E<9Ce[Fa'T*(HUe*_6DtZFl2[fqp\\kF!Q3k[G7E']ce'54Ya`Y+J2Z((FqZ&Km-[b&@cU"iT22%GrrXB7;8Ve-IP_@9T*?_F/ef+T?!)n.2I\!GotGq@NVmNgb;`"<D735/"$[q"Aaj=C\Nrq=@V"-[Q[3%+^h05+%stAE0H$m-JP\U>XWoJ7Cgj-/iqaQ6C%/W\%j`Qas#r]o8n@ICKc;G9+"[`ja*'8kD3:@msp3Y<Y-X/nHV`k$Pr~>endstream +endobj +111 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 92 +>> +stream +GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_H"Zg#ZYSJTP%YGC2U%ZDJ?(_?u0NYeAi<FV8*670]3GC~>endstream +endobj +112 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 636 +>> +stream +Gat$tbAs(+']&?qB1Y4B/.%0RZC.]@cD6B*UoS;[#X`Bh$Y$(7^67hBG1pPC`.0ZaS]B97J_Is<Zg<4s*6T'!j2c!i5m6b*][)5&!BVD--'ZM>,)IO2UJ0<gp+o:F^H^TZ,f1O_9OsCJr&(R.*]M:t8M1;cJg$j*'Q+`'K;GjLltFLuGMq>pElGko1IW.I+p6dY:P8k-@[a+01*c_LRmC+SBj0>"+odRMiOhC"k!/fcG3V;MggpLEK=ArK,8"Rf.gD3#8=iC3[q=sF?go7K7*6cpQo$"d?)MW"SXh`h6(CC,Z-Q/Jb@2>4TDao-mgmIjJbn>7k=n%4dcJuXhS@DE%(`CK@LJr>)MPdmO(KquG&*,R_GuHN?#A)ANRg>JIVloRT%4?SF,dWJ:/@5b958b+IPf#Uo3>A^4P`iNA=VADFqL=G'Rb[A)sDaW__`jh3%GrUe=Dl.4SPM+$D)7J&r0`N#<e^CSU*LCT.:IZH^TBM[lW8eUX&dlDigY6FGE^h6`KG79&V4hS$m-<7=/%7E@chb^8Y;jo/aC&2/?Ji4SJ.qDs-Ga0,So.;;M"h74rAnMZAl!!)f6sc>:Pr7Xjc`=8h46kp>`2RJuZ13U1QYiZqsSjZ;`C3J-/Uq]I0~>endstream +endobj +113 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 92 +>> +stream +GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_H"Zg#ZYSJTP%YGC2U%ZDJ?(_?u0NYeAi<FV8*670]3GC~>endstream +endobj +114 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2476 +>> +stream +Gb!ku9lJcW'#"0Do[,J!)1GN$*YoD:p=^&ZcUNiRi(JuE8\IKs[G=P-rqH#a8LgMeO6L$g#dB+0_'HY)WnsdX<HQ$(r!V:m?8;/&akg;./-spLc%=T+flFnm0$jN<(3E?l^?5_mQEVpb]NI(PYn"7V)/Fa$H#r+:Ck(Tlj1-8;nX&+&ea,&aSWY\s_Di#BI5<J-qd7Zua%!9U3#EChf!8c$SA#dn/S%.>VKkIp`,k'pBpcjGo:ja\Ahj!lk?k[Q125Cc<Z,[n/U-pW^Tch7g%&58jEGgjF)ReH2nlm5CIcqY0cB$2j1G(GUB3*.dNFM$EmN$t>6.ebr]bET<FaZVX.m_<@BsKg.u%Z@26UQdoJ^$1]nOUu9%9.AJo7cF@=*"uMk4V&$c_LaD:SW)V>&,V7r(tB.gg3HYC>L,rse$UXEjn-\ja]:oM*CQ/pr/*g`SGW4-@goJJ4p^$W#_=4GJ*tCHuB`hJ%O:[T8jQj+5PEJVPpN?/4n6[X;'^p7[9+>3QC`4Ik;Y\:44,X^rs*K]&bJo"*ZA.Dri%(rS`&^`N?6X4g,B`mgIIJaF\k9)^)X9-MS=Rd[[?2lr5oc1R:@^tWL'.6(oISeZ&pm?[:J*&5a^6@TcrSNXo-Kb$=tmha1rg5PC;'1OZ+nnkL$[?2Rp-'(ogYd2,a>-*E)'.h^nP5=0ornJN4\%Fl5;V3?u=I\&gg&6]F'R]glJBnO(4?nau=[7`HSLX:lok:Z&pTd9f_g\?/0E_No_mpA2X[K/^+AQS(2(m'50:N$gSqu4&gQAFh4aVH/:WA:7YT.Pa`er]N8JKB8(S*n[lV_`VH`^;egk0.=Qh\BZ%@khA?&'B$+"]:-C32)>1N7_?3tk[\r0a,:?ls:;+)BS/kukp),N1E+M@%'DRI>hoX(h[M#p+c+JHp*bIFo8SErR3%CWZl1^>MPS\X,Q[^(Y5,:T>=%T5O,m7W_(2B;MW%%J?TlMlT=5QJm^$4(RNA:%L25rUa3?>"RC_Bs"=\h@;@JEWBCE.Tp["kBQ?^f[-%gl93a,LioPX"I[eLc]5osE^b?hH/jPp.O'$U=YErr*HQ1-dM3^Y_ft,fO=m-$57!\?V]hGU2?iT-Hl=37-'1_IiC\nAWsq'VM$7Q_29Hh7XtRj0V$l7Ta!O:>7r\NOh:+H9a\-??>%Qf='Y@b/i4otd.N,;;rk`NLb$kpVb7t:`N""=4ij*`PJOOA2PT[fBEK/*s0B'DceYT@f5k7h')^>_54pd!d6L()Bp7u&+;=1;7N=3s%>PAaf8W-lrF)_J>Wkl&*b2TkC&,i84=D5FPVq<$h.";:/eMTp(SN4H-S]X\F,H1nK!DrEj<b5pt;90^*f5,Kfe&O,[OBbd#''$9^2,kE:o<$'ICdm0gTD2QANrikuMah)[_OEB7GWK(""uXr=W=F:)UIhiWbbAM)aNc,a6T6XOo`:8WkGuYYl*d#lrb*?un]tDq()&f$LE=*>/g8`]H'YfHg-<q-.P5`6?"h%IiZS^taG49JTj5'LUT%:m/1!ejVCUYpW55#F2s;q7bp\be$:c?)9],;i9Dta7'"65gfkg%qd[+7[=%LespRts$C*T6@3s"EdTO`T=4.cJ'RW60bFQ*hg@ED8;/2!Q&%@qS1Q4>PTK3(G:;GO+g/</@=lr$>4F\S\Ad_at#UF\/+K'ME"J+)hA/hFZ?$<'<M"&]DqYAL,c54)T;$Z7t(L,N>HD6J$bm7>FL.-S&YiQ-^-BK#+s*'J4+U$K:9=VpX+((DpP$"[?D^+5[I+)[>@b>LH[&tO*kON<MYU0nb(CYDhX@/Lkl6i56A6SdsSVCid2C;gte,FFeb('mO%i=N9%gbdpi(/7%HSA1*>l"';G@?SkF1HH3,35u"E/;8Hc(KXaT)P5Y(b#h'S);+\u[]*^4lH-ln(N+BZYp?R2M-R2phNRgWdVKo0*<&a%(;kCrK3\*I,ROFX!P*n;73S38!8D)T2[BJIN0r9BD?ufZ(Xu4<j(a.+YD]j(qg/8[T^;pXd,d4[6P)ekqo.3tA]qT#%&,.c'8E7kX#H("</[[n=2]s')l-%j\r(&e+*Ym%6iOUlgE+3!mQ]Qi]oJG'f=0AWb`?+L0oEm:0/r$,4C$`L?Q7erKKJPgrU!<m>1[Gcd.dK1BLG5e4`<MjSd,d$:k/A`Aa/%t39r:mM7,E/3L&?IqA9$GN?K-5iV`h`Ru>u?O(llQinqj0.,%#N&e`PD#O]VO]K?r.VQF*]Do[LhKP1P:%n:=oF/hQS+/139UFC<U*;d=X_9@\7riEfMeV%6P8;81unK$cictrC\^@ZI4C@QgBBJoeTU3lFLglO=<'ii_Xn*#n]gnW@@:l]-XJoTR[No"P7HV64>!`:q5^tTOplMi>""96>R[57nij*2VXDgg5+EI@R.(&OW9N&jZZ@c2$?UY&qgJ;W>=>VeV9_>r-[bqnRQrZlJC%mlFk=cg>q]]a$MG4m:r+#3i~>endstream +endobj +115 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1196 +>> +stream +Gb!#Y9lo;R&A@ZcqO![['[,,G:0St_W)U#.':_\'C+dAhA*k2V/'5$nqe_1N_(<g7\#go&=R+K'p\M9G"Sb@_1Ksq9V/SMn5XS'MTFm#'S\dbJq5Zl,4/7</1eqLNP(85!@>&X19Eqa"I@51J&(VaVN.sV(m190COmn(99Q:o50T%93+\$/UGFps(0bGV&#>f:e>lsE*cRD2=&X7o;BGa6,+CRK.U)6G)+!cIEo>AhK<5uYuk+<dp"4GL*rE#Weh\AQ"'a/t'&[i7\j-EnE!maI%J<40kMu+4:p%S&C(gmu0Zs;4OitDcr_6&*sH2h^g1KNPJH-NZ^ABYB,^O:]#<88$U98q/\1r<>sWc4ARcD,3P;Le6WRMr9](Dh<%[cH@TQqWFl_M;`G.5D!j=D4Qjj9dM9L@8BS7IUqC>64F[m+FG!J&Ogp();UYZ6_=_8)+TF#N-ds*7,iak9HU*@8mqG/""PX#WC_knAEgoH=S5o7%R,8WTB</9X&7J0'(&eJjQO"q<3sLU>UNn"C/cDIs@*XD8TcAdP(t':7fYYh$M31i5XAmi6csUiHs)l0H4Nt&mGJ8@DO*gCKW*P@iJ[UWoX#@7+YfdN,!ISpULWbnmI)1IG4(q7rmqqRJf00S85RR3^jK^i^6gs%:/Lc7/t/%nbVe\@jN]h8gJiL4aBIR1c_S5%AN;FOFB%=9o$pGHU5/a?FRN)G#LIo,eAIU#rHtArLODA1TU-P(tL<b`f38_q`]!=BD9m0pM"DB=9V,<1KP+:>2e892R$k29BVB>ECbFu5=.7^H?k%=k7koh%hC@D*iErENAI4hfra<pT<uC-D@diDm>Qu6^)c1M\(\h\R?6(6/B;@<pQt%*e"$0rGW%^-oPRRB)M_Q($`;bH4:Hh]>gno3pCe:ZTJueRL5uLScr516]l?@[r$#ZP2)uQob;).b]5B9h;DhGa-!PBUjG]!3;SWb[*"A[#jZ,68=E>1c=^\Wkh,`<J&W-;I!%W#Y2PsmtMMuQ!?Ri!><FP=mkLo<b:D;`4,_1]IZ<aCZc4CiL30n+kG(U@gWj$9g\r2Ti#gclh_aH;&aCrP(_r2!I)tZ8NChmOkGu?/)<>Y'nJ-JK<^!9,RE2-+bPkb(P]iqMt%D?Ga@1X\0UaY"/Y4D);9n)\71@)*GU\jYLMgu<#i?[\9#u1ErH-o3(kkkP8F+p1~>endstream +endobj +116 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2694 +>> +stream +Gb!;f>B?:T&q9SYkXR!H'4sL7p>qN;H]iN:2t86K8o9i#&.I"*#da\9f"^,1!FZ,:5q8KiG+=_+dgX_(p"-Yb!u$0OILT?Y+(t*%'*H6_('ClP)eR^khq?]?B<7E+9uCL?G7(M5)P6'FGTU6M4K/7/qg<!XYW4LegG_.Z^T#1T$5\Y%Re!GoD4:R>K+d\DrRi:&&FP'+S$MP3C^&%\pM8P&#NjCa%*#3R%gI6fCJVdN*7ORs>T_7@c,+KIdK3A`7&s])o.:YLYnHM5p(M',8Y&*<U\ZHC;o<thPrRXnKM$?C<-%2n<19PP#?:Q)$jt(B=d_ZsKaS+ta;D't3Thmu+;GhDF.rRh6:5WJ)P/;6pjOGqlAK>,S_KOcD0XB@*:PJJ[dRn_KIkPWJ=4CkYK\7N^LaR[e*Z/bml`P="W(2KSo<"@r$+Kn(n%``6\HK+p?4:6'YiP_#U+cO(n>s.[:$GBp[[:,?12X.!1a(TD4ntknF1^kj[C4?\M!M4+&t<[@():[a>?T58E;JNMBtU_G:CGA]EhJfQO9!HAQ[#)V$57J+j<uf+H7M+WIT>hEk7!TfGVN$XduXN<'`V\,0f5_5^d+86lHD7"bfc.8;s--4Q.'95D6Vg:-j;``r?Wo`\:*>.-EZfJ6mqs)J@X=3>+b''7lB@j%Q.\2&>eb/>*2ok8WU[>(eYs+[k<rL*H(I"(I0VDKuVC6)m'R<sDoL>o)HTF/K,-3S#.gbX*=$#N_Hh1"4?k#.Wb\mR!=26G]:nI"72ET%<Zs48b8Ll9X.sJKRI/a"fpbp1+Kk[6haRF>4j"WB5X:FV<""G!nM*BFW_d*Re`Cffk^4Zp'(cBspU\R+XS6WuOq?nPitg@774Q@[;lXX:l0gaS.HV2-jp!@qmdV@=%`p\]BcLUD"I]HQ0e9#;F1'.]aano,?+*"D^?E8i0B`[hA-c4BmZbS+OmjYOLTCgUG?ZZbIo]e*l2o]Xdk7D)U5oXJ'$=RKe7qA^'>,CTTC(2k`Q3:qb*KD"0:RGY>4b**5A8or&1%W^=_b@1Og@g?#5\8I-`+aB3(UEWYW(Gos*dAmM=fm"ke(h$C[UpjGhD%\cK,M\5e5dV5&?*U"CI\fB6o`(DQ).[g/6n\U[?EjcuW7l.9,^gR8e*q[N'e9+K'32X`E*CHu=fOcG.18S/.6U0@8I40-A9Ko/s-7]Dn`C5NlKCkT?9OIG&D4II?9XYU_9AMFtBuk&A7,5o7UgH\k*"D&P(;rAIGo7n&OkPb$7ef"<#&H+E^mm@BkP[H\`Wk+kLRIjMF\:ci<:P1ULcA%c*$\6c.#I0nWu.BkT'8'YFd#*T;:dbJ2KBm5Mb+IXObmk6GCF-fO.5N`D\P,Hn+/Co:W3d$b6eE1?C:8pn.DI5@O=CP."d6;K19!6C8g1(IESmgaB%"FU3`,VnDE/5htIp+%AiI`!@U,&NC);pco#1!K'Pr%YauZOYn:m"Z.$a2!qT;n1%4hlGegs8mb+aO^VUWPUPPoBR[5dd3lu(qQ.W1?e1oYK!giC]2RV6FFY@$0)6cRApIM8tQ=m$$Yu=K8,@!H+9U4*Iib.d(_Qpu<..j6lXLW6q2L(#(M7,4-$+@(;l]70Be7Pf0rA4PupD\[m`F6(lM@WC#*39`cMW9Yiq308gm?l5jQJumC'$)m_YU74Hh&GgBATSl^_ZHd1o*QB6m-L-tmA&giQL2)e4Jmh58\GQ#Od6=@@nR>lpA6m]A6N!^+qujJX`dc)%IK='/f$4=ZN46%#76jJ;P9XY2Fp>Wf!9Rrb_ZCefa,6&cAkPrmC)D?fQ:?)#umZ>$H:Zk;+(jJg+G(c''T\"=9M'l"O5,j3I%OWIJ7up[Hr39JGV!AGkJgZ>Pi4a_N$1het^=*?,*5c$09g`Qr2Cjef2s`C/jN!?Kji5,t>qm%;1i8GPKnu2K@>`G(66:_]"*Xbbdblc#BV=Ac0JtpS%G+GQ,-g,4qhqi(U]c-M^qR(I`K"9B6L\\<M[QM4LDEfZ)sUJ8Mum_ep1VYR^Gj_VhW/b3cb'aMNm?mXPq&!Z3KF[TdeGJo8+IAL)F(SaA+/4'e4B]f(/Kb;"JH%+BX*@(=G=.-@'[ZQO>4Zk+^a=jUCf)hGCpG6$JgX#eA(q:%LQ*06"<5SCG#.hiscPW)=o*',Wc`J$!=F7_:Xd@og[F\g_Z-tBB1Z9QO>3eGuJ/SNIif@B\E07&]bmkoRM+t,b+V7GfMW^GQJ>UD;&-'PgeAs/5C(s*j(9KFG,T>ZG5qr$t25ldh:b1042l_kt#!_);C_/<MUCJ1W\04JFh7rHl)mq+#dAab.u0)D?8[Y+3al/XFkWR42oYQ/_LZfDdT%-EfOCi:^g&HI7I^u9KCEmp]jR0ZI3D&TKd87+]o_j@n@e.urJJ%`S1I951hlh:p[9#BIsW3SOD$htmo.,3qffkS?Oj6TgmQcO^`ZM@:t.I+mTAQh8k7_:l(o'RY%?`+7SI=%rDc9Y_KF81ULBk`oe<7Z92IbQT[-u#cJ^fS%Y\N2_U[-dh1[u_X7Nh??>VX%%4Y.gC@FWEWd@81+A+t$0e+Y@_XT`R7mUMk((fZiW2hgq2BPsR!:<8h'-5k)417n8jV#P<>Q8E("N0h!3`FSaQV0j(WC3\4!s)bu@MK4>?npB^lDXp$r3d@<7ZUT<qF^N/!i'H:`+FkO*g++EF\ZT+KR""2]263~>endstream +endobj +117 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 822 +>> +stream +Gb!;`bAQ&g&A7ljp?2\e,>o%U\J,M$"9EOV$N[s%6;*Q]ee/XYWggclP*TW?G*Dc)bE.895%]SV9-M*+qKLcr>\A#$97\k>8tZcQ+FAXbg$EuR#L=e@!KD@5SAul\dg4uGJNrM$fbbh+G]jXh^d[GgT(bS8KE<BeK+'RZ0qMq[bTA:s+!CF]fbn%2m9&C!52/+LS-g;!hdkPD)54k$ee3r0]3I\%<YBeZbM-QHS?#,XQILP4N1Z_p$S6DV2mTisJ59P?U!t+<e_4,hGO!::X"=SZ!cB&#aOnB5Hlr>bP)h]CHu_3'e2bBE-+rF_6mn\VWia'Ok`#`$Y$QKK]D/F%4Oko?YYrY>F>$]#4WFJmha@F86^[ih+sUgcIV9u7=0Dd"6]reAO%-8TEa53,,Y#&g^%KubCtIjY`tZ,WL-^@;.)=Yc)Qr827R=Bb-u2)A6G$.Vdep]aGAcBL6]_j;W=UN2r4h(48-j!A-V=IFq]F,sdYjN&()%HPa=)-%8[ptUFnXM*,KEmF^5fH8(R/]p:_lPM&=,!k`B_9ci/>ZTpq7HoWVlaX1"O.O;qB'<S5`p^DEkk=j+Qm0[ti*lBFr$)ArK*cIcEW\\'l[^%1o$q;&$q/m9HB<CI%l"jq+^l@VX`&$HP(CF,NDD1CL_&i's,>GBd#D[ZrAE0X_cWFFM,-k+[sPn.<(^b2lu=*P\eX?593ZjZ/d`T>mS1Le<!?]"Qf'cS\,MJ>NYGNNLfJ;Jj76>W7l(VY*<Q]uffI6Pp7BMguI1=`XA9],Bgb:5bhY:U'KGXc\*%2&/PG-Ce"`HI:eREgZe+h7h,/~>endstream +endobj +118 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1470 +>> +stream +Gb!#Z9lo;R&A@ZcqFIob=Rm9PSsW5C9l4K$)48R#Mm6ipNGWql)j:$igQI-?"S/fTLCL686rJ6Df<;eT_86^?J&;]Qo,KB['I\TZ%+HF1b\uEShYY]qgRX?n/F*'apmt8Np=R3&\4fB=r-l9G&K<Vk13UYQKC5L>ol:mID96?A@?*]@5G@0-q7Lp,L+i\?&'DngGm8AlT/RT*"7#-t#\C.p#/WLb4"_*!Zi#r<p7Zt?ElIX3K?U#]38D\4NSn,2pr\q90`MC?k8Mg?nb3Z_m1S_di*prr">7B`EI%D[EOeX6)n<$aW@AXKU8Sid0a3EX3#'2d^B9\M`akKKN4BUc%NoPmDjfr2b),HL5j"P2!0@<jK'*E"Et''c-'7W'M!GaC*m6;H.Y2qH*@?:`oU4t)%Mo"Waa_f&YL4ecW!=C20NlEg?-SWuW"s$<hF?gjqua=E[HQ8<0/0_BOSbNlL9-u_P#,cZE,,9gq$"(/a2C%c)lhLRWgcR*QQ0lTcHO'A^f;E[KrWUpi_a>3aRT/h']$gBe2=Uch2c)KB:'a(^:24'7s:A\Z)rLpK<>K>g!WhUln9Tb2Z8Ydj7@oW2^Q<H*APSm$DcE'YY3SCa#f5_nA)F_2`sW.GVY#2LIj,8+GC:*#hFPtK4TqW?1Y@a/mf)bUL@=r,%$af)4Y".@!gSu"ZJ`]Wa#./Zq?0ND0sKcDSPRpKWd[J@i1.'4:u--=-:j\/C*rQ)BePHC!S0TG%b=3^Ufsfc<tCe%;#bS7>r3'i.tFuVqo5D$(kY_4Q#l)qo.(<14@;(I*!mFL'\L?Yje0QD'31>P,@YS6)HO69N>]';?s];bYK7OKV_pgW0`!W%m;k5:h&]YY)XGLU,WP'#G_<iYtKWg-V[GY78O1+8"9omQ9d%:GEdes&at3/>5lOcPfPpq'I_C81V^\S#:.lToT@6^$*udr'U,/mH6C:H(r9,$'ssm!;!lCg2KB#+6n<SjCiKC;dA0H:osd>ZMY5q=q2TY&?C<qo>1TOB@cegH.]eo<'h&*]).+>SVSe0oDK(2ID%Cm*&iofe,fBb$R)-3un.%lHT%B_*8H0Xg:,]t<qK`7^Y+e2'\Cq(a$[aU"\OK=jca2Ss=YknU$+O4EH1`uo/e$M4Z,$7"!a1,rMH'(9(YXEp,blj.ZI[!%k7Jb.7EBQ#m<jSuNor?\YMo'Z>ulKH3Ks\N*^D%slpYRkh6i75a,je[0h^8Gn/;kf<?b*+F73%?!/\sbl0J`-kV`dr1llN./loGmg/oG\e*PT;D-oZW`6j$q<)oVU?!QTO5YtK*k)]C45c`?X#h)kl$7="MQu,tF?tTni!2sbFE31REadVBMLEXlV;/p!02<[[&0=_QB3Ij=@J>M_E"8GW'A:dj2UPliRh8Pd<B#F/[UBB=N+g+J%_\T$Y9!5kDG.&>ZQ;8?/hJ4Ecr8R>jYMOWPf[i7CVuF_"qZk-7pFj*8DA`~>endstream +endobj +119 0 obj +<< +/Nums [ 0 120 0 R 1 121 0 R 2 122 0 R 3 123 0 R 4 124 0 R + 5 125 0 R 6 126 0 R 7 127 0 R 8 128 0 R 9 129 0 R + 10 130 0 R ] +>> +endobj +120 0 obj +<< +/S /D /St 1 +>> +endobj +121 0 obj +<< +/S /D /St 2 +>> +endobj +122 0 obj +<< +/S /r /St 1 +>> +endobj +123 0 obj +<< +/S /r /St 2 +>> +endobj +124 0 obj +<< +/S /D /St 1 +>> +endobj +125 0 obj +<< +/S /D /St 2 +>> +endobj +126 0 obj +<< +/S /D /St 3 +>> +endobj +127 0 obj +<< +/S /D /St 4 +>> +endobj +128 0 obj +<< +/S /D /St 5 +>> +endobj +129 0 obj +<< +/S /D /St 6 +>> +endobj +130 0 obj +<< +/S /D /St 7 +>> +endobj +xref +0 131 +0000000000 65535 f +0000000073 00000 n +0000000158 00000 n +0000000265 00000 n +0000000377 00000 n +0000000584 00000 n +0000000791 00000 n +0000000959 00000 n +0000001127 00000 n +0000001295 00000 n +0000001463 00000 n +0000001632 00000 n +0000001801 00000 n +0000001970 00000 n +0000002139 00000 n +0000002308 00000 n +0000002477 00000 n +0000002646 00000 n +0000002815 00000 n +0000002984 00000 n +0000003153 00000 n +0000003322 00000 n +0000003491 00000 n +0000003660 00000 n +0000003829 00000 n +0000003998 00000 n +0000004167 00000 n +0000004336 00000 n +0000004505 00000 n +0000004674 00000 n +0000004843 00000 n +0000004959 00000 n +0000005128 00000 n +0000005297 00000 n +0000005466 00000 n +0000005635 00000 n +0000005804 00000 n +0000005973 00000 n +0000006142 00000 n +0000006311 00000 n +0000006480 00000 n +0000006649 00000 n +0000006818 00000 n +0000006987 00000 n +0000007156 00000 n +0000007325 00000 n +0000007816 00000 n +0000008024 00000 n +0000008135 00000 n +0000008343 00000 n +0000008551 00000 n +0000008671 00000 n +0000008859 00000 n +0000009053 00000 n +0000009247 00000 n +0000009419 00000 n +0000009607 00000 n +0000009801 00000 n +0000009995 00000 n +0000010167 00000 n +0000010355 00000 n +0000010638 00000 n +0000010832 00000 n +0000011026 00000 n +0000011198 00000 n +0000011386 00000 n +0000011596 00000 n +0000011768 00000 n +0000012030 00000 n +0000012136 00000 n +0000012317 00000 n +0000012528 00000 n +0000012725 00000 n +0000012936 00000 n +0000013184 00000 n +0000013364 00000 n +0000013591 00000 n +0000013771 00000 n +0000013981 00000 n +0000014191 00000 n +0000014411 00000 n +0000014631 00000 n +0000014849 00000 n +0000015071 00000 n +0000015247 00000 n +0000015523 00000 n +0000015631 00000 n +0000015889 00000 n +0000015964 00000 n +0000016103 00000 n +0000016264 00000 n +0000016377 00000 n +0000016500 00000 n +0000016623 00000 n +0000016746 00000 n +0000016869 00000 n +0000016991 00000 n +0000017172 00000 n +0000017314 00000 n +0000017459 00000 n +0000017602 00000 n +0000017763 00000 n +0000017908 00000 n +0000018049 00000 n +0000018223 00000 n +0000018354 00000 n +0000018547 00000 n +0000018677 00000 n +0000018811 00000 n +0000019307 00000 n +0000019490 00000 n +0000020502 00000 n +0000020685 00000 n +0000021413 00000 n +0000021596 00000 n +0000024165 00000 n +0000025454 00000 n +0000028241 00000 n +0000029155 00000 n +0000030718 00000 n +0000030868 00000 n +0000030903 00000 n +0000030938 00000 n +0000030973 00000 n +0000031008 00000 n +0000031043 00000 n +0000031078 00000 n +0000031113 00000 n +0000031148 00000 n +0000031183 00000 n +0000031218 00000 n +trailer +<< +/ID +[<2db82f8d13fc9aad0f6ac8c1445975f3><2db82f8d13fc9aad0f6ac8c1445975f3>] +% ReportLab generated PDF document -- digest (http://www.reportlab.com) + +/Info 86 0 R +/Root 85 0 R +/Size 131 +>> +startxref +31253 +%%EOF +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 30 0 R /F4 47 0 R /F5 50 0 R /F6 68 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 108 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/Contents 109 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 48 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 40.01575 754.0394 98.34575 766.0394 ] /Subtype /Link /Type /Annot +>> +endobj +7 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 48 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 754.7894 555.2598 766.7894 ] /Subtype /Link /Type /Annot +>> +endobj +8 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 60.01575 736.0394 152.2657 748.0394 ] /Subtype /Link /Type /Annot +>> +endobj +9 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 736.7894 555.2598 748.7894 ] /Subtype /Link /Type /Annot +>> +endobj +10 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 721.8394 0 ] /Rect [ 80.01575 718.0394 130.5857 730.0394 ] /Subtype /Link /Type /Annot +>> +endobj +11 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 721.8394 0 ] /Rect [ 549.6998 718.7894 555.2598 730.7894 ] /Subtype /Link /Type /Annot +>> +endobj +12 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 587.0394 0 ] /Rect [ 80.01575 700.0394 126.6957 712.0394 ] /Subtype /Link /Type /Annot +>> +endobj +13 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 587.0394 0 ] /Rect [ 549.6998 700.7894 555.2598 712.7894 ] /Subtype /Link /Type /Annot +>> +endobj +14 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 410.2394 0 ] /Rect [ 80.01575 682.0394 126.1457 694.0394 ] /Subtype /Link /Type /Annot +>> +endobj +15 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 410.2394 0 ] /Rect [ 549.6998 682.7894 555.2598 694.7894 ] /Subtype /Link /Type /Annot +>> +endobj +16 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 197.4394 0 ] /Rect [ 80.01575 664.0394 126.1457 676.0394 ] /Subtype /Link /Type /Annot +>> +endobj +17 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 197.4394 0 ] /Rect [ 549.6998 664.7894 555.2598 676.7894 ] /Subtype /Link /Type /Annot +>> +endobj +18 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 86.63937 0 ] /Rect [ 80.01575 646.0394 126.7057 658.0394 ] /Subtype /Link /Type /Annot +>> +endobj +19 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 60 0 R /XYZ 40.01575 86.63937 0 ] /Rect [ 549.6998 646.7894 555.2598 658.7894 ] /Subtype /Link /Type /Annot +>> +endobj +20 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 40.01575 699.0394 0 ] /Rect [ 80.01575 628.0394 179.4857 640.0394 ] /Subtype /Link /Type /Annot +>> +endobj +21 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /XYZ 40.01575 699.0394 0 ] /Rect [ 549.6998 628.7894 555.2598 640.7894 ] /Subtype /Link /Type /Annot +>> +endobj +22 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 60.01575 610.0394 191.7357 622.0394 ] /Subtype /Link /Type /Annot +>> +endobj +23 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 610.7894 555.2598 622.7894 ] /Subtype /Link /Type /Annot +>> +endobj +24 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 80.01575 592.0394 245.0857 604.0394 ] /Subtype /Link /Type /Annot +>> +endobj +25 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 549.6998 592.7894 555.2598 604.7894 ] /Subtype /Link /Type /Annot +>> +endobj +26 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 617.0394 0 ] /Rect [ 80.01575 574.0394 226.7257 586.0394 ] /Subtype /Link /Type /Annot +>> +endobj +27 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 617.0394 0 ] /Rect [ 549.6998 574.7894 555.2598 586.7894 ] /Subtype /Link /Type /Annot +>> +endobj +28 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 464.2394 0 ] /Rect [ 80.01575 556.0394 200.0657 568.0394 ] /Subtype /Link /Type /Annot +>> +endobj +29 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 464.2394 0 ] /Rect [ 549.6998 556.7894 555.2598 568.7894 ] /Subtype /Link /Type /Annot +>> +endobj +30 0 obj +<< +/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +31 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 383.4394 0 ] /Rect [ 80.01575 538.0394 261.7657 550.0394 ] /Subtype /Link /Type /Annot +>> +endobj +32 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 383.4394 0 ] /Rect [ 549.6998 538.7894 555.2598 550.7894 ] /Subtype /Link /Type /Annot +>> +endobj +33 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 314.6394 0 ] /Rect [ 80.01575 520.0394 187.8357 532.0394 ] /Subtype /Link /Type /Annot +>> +endobj +34 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 73 0 R /XYZ 40.01575 314.6394 0 ] /Rect [ 549.6998 520.7894 555.2598 532.7894 ] /Subtype /Link /Type /Annot +>> +endobj +35 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 40.01575 723.0394 0 ] /Rect [ 80.01575 502.0394 232.8457 514.0394 ] /Subtype /Link /Type /Annot +>> +endobj +36 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 75 0 R /XYZ 40.01575 723.0394 0 ] /Rect [ 549.6998 502.7894 555.2598 514.7894 ] /Subtype /Link /Type /Annot +>> +endobj +37 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 60.01575 484.0394 210.6257 496.0394 ] /Subtype /Link /Type /Annot +>> +endobj +38 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 787.0394 0 ] /Rect [ 549.6998 484.7894 555.2598 496.7894 ] /Subtype /Link /Type /Annot +>> +endobj +39 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 80.01575 466.0394 190.6157 478.0394 ] /Subtype /Link /Type /Annot +>> +endobj +40 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 751.8394 0 ] /Rect [ 549.6998 466.7894 555.2598 478.7894 ] /Subtype /Link /Type /Annot +>> +endobj +41 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 671.0394 0 ] /Rect [ 80.01575 448.0394 430.1857 460.0394 ] /Subtype /Link /Type /Annot +>> +endobj +42 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 671.0394 0 ] /Rect [ 549.6998 448.7894 555.2598 460.7894 ] /Subtype /Link /Type /Annot +>> +endobj +43 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 567.4394 0 ] /Rect [ 80.01575 430.0394 205.0457 442.0394 ] /Subtype /Link /Type /Annot +>> +endobj +44 0 obj +<< +/Border [ 0 0 0 ] /Contents () /Dest [ 84 0 R /XYZ 40.01575 567.4394 0 ] /Rect [ 549.6998 430.7894 555.2598 442.7894 ] /Subtype /Link /Type /Annot +>> +endobj +45 0 obj +<< +/Annots [ 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R + 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R + 26 0 R 27 0 R 28 0 R 29 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R + 37 0 R 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R ] /Contents 110 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +46 0 obj +<< +/Contents 111 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +47 0 obj +<< +/BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +48 0 obj +<< +/Contents 112 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +49 0 obj +<< +/Contents 113 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +50 0 obj +<< +/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +51 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 119.4957 615.0394 140.8121 627.0394 ] /Subtype /Link /Type /Annot +>> +endobj +52 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.gnu.org/licenses/agpl-3.0.html) +>> /Border [ 0 0 0 ] /Rect [ 208.4357 231.4394 316.8057 243.4394 ] /Subtype /Link /Type /Annot +>> +endobj +53 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com/licensing/commercial/) +>> /Border [ 0 0 0 ] /Rect [ 353.4957 231.4394 446.2857 243.4394 ] /Subtype /Link /Type /Annot +>> +endobj +54 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 471.8457 231.4394 500.1857 243.4394 ] /Subtype /Link /Type /Annot +>> +endobj +55 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 241.2357 213.4394 261.2457 225.4394 ] /Subtype /Link /Type /Annot +>> +endobj +56 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.gnu.org/licenses/agpl-3.0.html) +>> /Border [ 0 0 0 ] /Rect [ 208.4357 132.6394 316.8057 144.6394 ] /Subtype /Link /Type /Annot +>> +endobj +57 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com/licensing/commercial/) +>> /Border [ 0 0 0 ] /Rect [ 353.4957 132.6394 446.2857 144.6394 ] /Subtype /Link /Type /Annot +>> +endobj +58 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 471.8457 132.6394 500.1857 144.6394 ] /Subtype /Link /Type /Annot +>> +endobj +59 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 343.4657 114.6394 391.9252 126.6394 ] /Subtype /Link /Type /Annot +>> +endobj +60 0 obj +<< +/Annots [ 51 0 R 52 0 R 53 0 R 54 0 R 55 0 R 56 0 R 57 0 R 58 0 R 59 0 R ] /Contents 114 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +61 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.gnu.org/licenses/agpl-3.0.html) +>> /Border [ 0 0 0 ] /Rect [ 208.9957 745.0394 317.3657 757.0394 ] /Subtype /Link /Type /Annot +>> +endobj +62 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com/licensing/commercial/) +>> /Border [ 0 0 0 ] /Rect [ 354.0557 745.0394 446.8457 757.0394 ] /Subtype /Link /Type /Annot +>> +endobj +63 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 472.4057 745.0394 500.7457 757.0394 ] /Subtype /Link /Type /Annot +>> +endobj +64 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/download) +>> /Border [ 0 0 0 ] /Rect [ 344.0257 727.0394 392.1558 739.0394 ] /Subtype /Link /Type /Annot +>> +endobj +65 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://en.wikipedia.org/wiki/Aladdin_Free_Public_License) +>> /Border [ 0 0 0 ] /Rect [ 142.8457 640.2394 167.8557 652.2394 ] /Subtype /Link /Type /Annot +>> +endobj +66 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 182.2957 598.2394 210.6357 610.2394 ] /Subtype /Link /Type /Annot +>> +endobj +67 0 obj +<< +/Annots [ 61 0 R 62 0 R 63 0 R 64 0 R 65 0 R 66 0 R ] /Contents 115 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +68 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font +>> +endobj +69 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://bugs.ghostscript.com) +>> /Border [ 0 0 0 ] /Rect [ 388.7157 642.0394 489.3006 654.0394 ] /Subtype /Link /Type /Annot +>> +endobj +70 0 obj +<< +/A << +/S /URI /Type /Action /URI (file:///home/cliddell/artifex/ghostpdl-release/doc/COPYING) +>> /Border [ 0 0 0 ] /Rect [ 188.6357 561.2394 302.5657 573.2394 ] /Subtype /Link /Type /Annot +>> +endobj +71 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://ghostscript.com/doc/current/News.htm) +>> /Border [ 0 0 0 ] /Rect [ 63.01575 327.6394 88.01575 339.6394 ] /Subtype /Link /Type /Annot +>> +endobj +72 0 obj +<< +/A << +/S /URI /Type /Action /URI (file:///home/cliddell/artifex/ghostpdl-release/doc/COPYING) +>> /Border [ 0 0 0 ] /Rect [ 40.01575 177.8394 71.13575 189.8394 ] /Subtype /Link /Type /Annot +>> +endobj +73 0 obj +<< +/Annots [ 69 0 R 70 0 R 71 0 R 72 0 R ] /Contents 116 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +74 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/) +>> /Border [ 0 0 0 ] /Rect [ 302.3557 676.2394 396.8157 688.2394 ] /Subtype /Link /Type /Annot +>> +endobj +75 0 obj +<< +/Annots [ 74 0 R ] /Contents 117 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +76 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://www.ghostscript.com/) +>> /Border [ 0 0 0 ] /Rect [ 40.01575 687.7894 134.4757 699.7894 ] /Subtype /Link /Type /Annot +>> +endobj +77 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/en/ps/PLRM.pdf) +>> /Border [ 0 0 0 ] /Rect [ 431.8757 619.4394 553.0774 631.4394 ] /Subtype /Link /Type /Annot +>> +endobj +78 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/en/ps/PLRM.pdf) +>> /Border [ 0 0 0 ] /Rect [ 40.01575 607.4394 192.4259 619.4394 ] /Subtype /Link /Type /Annot +>> +endobj +79 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf) +>> /Border [ 0 0 0 ] /Rect [ 212.3057 607.4394 333.2395 619.4394 ] /Subtype /Link /Type /Annot +>> +endobj +80 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/pdf/index_reference.html) +>> /Border [ 0 0 0 ] /Rect [ 335.6057 595.4394 464.5796 607.4394 ] /Subtype /Link /Type /Annot +>> +endobj +81 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/acrobat/sdk/index.html) +>> /Border [ 0 0 0 ] /Rect [ 470.6557 595.4394 555.2598 607.4394 ] /Subtype /Link /Type /Annot +>> +endobj +82 0 obj +<< +/A << +/S /URI /Type /Action /URI (http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html) +>> /Border [ 0 0 0 ] /Rect [ 80.03575 583.4394 330.1257 595.4394 ] /Subtype /Link /Type /Annot +>> +endobj +83 0 obj +<< +/A << +/S /URI /Type /Action /URI (https://www.artifex.com) +>> /Border [ 0 0 0 ] /Rect [ 156.1757 478.6394 261.6142 490.6394 ] /Subtype /Link /Type /Annot +>> +endobj +84 0 obj +<< +/Annots [ 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R 81 0 R 82 0 R 83 0 R ] /Contents 118 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 107 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 + /Trans << + +>> /Type /Page +>> +endobj +85 0 obj +<< +/Outlines 87 0 R /PageLabels 119 0 R /PageMode /UseNone /Pages 107 0 R /Type /Catalog +>> +endobj +86 0 obj +<< +/Author () /CreationDate (D:20000101000000+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20000101000000+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) + /Subject (\(unspecified\)) /Title () /Trapped /False +>> +endobj +87 0 obj +<< +/Count 23 /First 88 0 R /Last 88 0 R /Type /Outlines +>> +endobj +88 0 obj +<< +/Count 18 /Dest [ 48 0 R /XYZ 40.01575 787.0394 0 ] /First 89 0 R /Last 103 0 R /Parent 87 0 R /Title (Introduction) +>> +endobj +89 0 obj +<< +/Count 6 /Dest [ 60 0 R /XYZ 40.01575 787.0394 0 ] /First 90 0 R /Last 95 0 R /Next 96 0 R /Parent 88 0 R + /Title (What is Ghostscript?) +>> +endobj +90 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 721.8394 0 ] /Next 91 0 R /Parent 89 0 R /Title (Ghostscript) +>> +endobj +91 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 587.0394 0 ] /Next 92 0 R /Parent 89 0 R /Prev 90 0 R /Title (GhostPDF) +>> +endobj +92 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 410.2394 0 ] /Next 93 0 R /Parent 89 0 R /Prev 91 0 R /Title (GhostPDL) +>> +endobj +93 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 197.4394 0 ] /Next 94 0 R /Parent 89 0 R /Prev 92 0 R /Title (GhostPCL) +>> +endobj +94 0 obj +<< +/Dest [ 60 0 R /XYZ 40.01575 86.63937 0 ] /Next 95 0 R /Parent 89 0 R /Prev 93 0 R /Title (GhostXPS) +>> +endobj +95 0 obj +<< +/Dest [ 67 0 R /XYZ 40.01575 699.0394 0 ] /Parent 89 0 R /Prev 94 0 R /Title (URW Font Information) +>> +endobj +96 0 obj +<< +/Count 6 /Dest [ 73 0 R /XYZ 40.01575 787.0394 0 ] /First 97 0 R /Last 102 0 R /Next 103 0 R /Parent 88 0 R + /Prev 89 0 R /Title (Document roadmap by theme) +>> +endobj +97 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 751.8394 0 ] /Next 98 0 R /Parent 96 0 R /Title (What should I read if I\220m a new user?) +>> +endobj +98 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 617.0394 0 ] /Next 99 0 R /Parent 96 0 R /Prev 97 0 R /Title (GPL and commercial Ghostscript) +>> +endobj +99 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 464.2394 0 ] /Next 100 0 R /Parent 96 0 R /Prev 98 0 R /Title (Before building Ghostscript) +>> +endobj +100 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 383.4394 0 ] /Next 101 0 R /Parent 96 0 R /Prev 99 0 R /Title (What should I read if I\220m not a new user?) +>> +endobj +101 0 obj +<< +/Dest [ 73 0 R /XYZ 40.01575 314.6394 0 ] /Next 102 0 R /Parent 96 0 R /Prev 100 0 R /Title (What if I\220m a developer?) +>> +endobj +102 0 obj +<< +/Dest [ 75 0 R /XYZ 40.01575 723.0394 0 ] /Parent 96 0 R /Prev 101 0 R /Title (What if I\220m writing documentation?) +>> +endobj +103 0 obj +<< +/Count 3 /Dest [ 84 0 R /XYZ 40.01575 787.0394 0 ] /First 104 0 R /Last 106 0 R /Parent 88 0 R /Prev 96 0 R + /Title (Presence on the World Wide Web) +>> +endobj +104 0 obj +<< +/Dest [ 84 0 R /XYZ 40.01575 751.8394 0 ] /Next 105 0 R /Parent 103 0 R /Title (Ghostscript\220s home page) +>> +endobj +105 0 obj +<< +/Dest [ 84 0 R /XYZ 40.01575 671.0394 0 ] /Next 106 0 R /Parent 103 0 R /Prev 104 0 R /Title (Adobe PostScript, Encapsulated PostScript, and PDF reference documentation) +>> +endobj +106 0 obj +<< +/Dest [ 84 0 R /XYZ 40.01575 567.4394 0 ] /Parent 103 0 R /Prev 105 0 R /Title (Other material on the WWW) +>> +endobj +107 0 obj +<< +/Count 11 /Kids [ 4 0 R 5 0 R 45 0 R 46 0 R 48 0 R 49 0 R 60 0 R 67 0 R 73 0 R 75 0 R + 84 0 R ] /Type /Pages +>> +endobj +108 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 404 +>> +stream +Gatn!b>,r/&4Q?mMHN7L_p!Al,YKUQ2m=_*#MP>-&Ufaqa62KYBh=6"6UHWm`P&P&ad@Y=`V":-#NuCP]4><#0EkKV#ZksWbd69*WJ&2BEKDFUa^uI+M_V*5\ShZV/\DtF1a@SM=)i-oE6?^':)o-@K-_pdkkE<*>)("1"t3djFb&%AP%sYq,i]n]`0s1m!MKj"C/">YP":PL*?5M0QKrQS.;#UnY"+D:dF0h'7gQf<J%HQZL@s,)"nd?J,Mesqm8f<S4c-NY'M=K9F,f-o?E@e_"`OT6g=bl&](N_:7c'8!L48/WF`thR\/W9`=V7-thp1/m-th$,r=c:JG(VeTFImk-SJ+G0$9nS5*bHRRid=+<S$0t^50aNI5)G[ulT_h8hpAf>ISg+:!BZOU>l~>endstream +endobj +109 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 92 +>> +stream +GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_H"Zg#ZYSJTP%YGC2U%ZDJ?(_?u0NYeAi<FV8*670]3GC~>endstream +endobj +110 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 920 +>> +stream +GauI7?Z2Df'ZJu*'_a>_<e?;?j_7ouUl&,cC!2`(m"Ku=0EmsaZ>/9G"p/Ya]%fQ*&g\+oTC]D6\L%G1r?C?9QiLCf0V/gu'`96gAhrlEi5R^))J"%=ZV69rQ\4UEe$;-6YLCbY"]XrG>Jmi,fe>SO=VUSEe<?$33@T:6Padml!k&8)^u^u(YIi3YUp6`7';21UnUptO$<&:FS9\L?LUrFsBfhW-_0"!W\rpb[dQIC,rX\ME$K(ShY:]4%\rCp7Ct-aFp/7b)JN)X*f[R$:pMA9pAp&Q2Zb!ka1q?%;LQpYmBs)!R%J*]!n,$VgDG4f=rGMV/qk@1QE#b&rh<7?_,.5enX.q7DNFdAe/Gb*Z]YcU6"ZaL=gob1RB;(2Aq'Q;PXbbm[n+,.&53e7G+%,V4i]<%K#RuFJgAS6ff+S9cXYL:ukC&cd&59LS0MHXO23)1X_D'[<a>a26Bh-0?9]'HC#UV<?9N^+\ip4K%-G',j1gN_="Lsh;'RT@),TjR1k63d+Y@Y4<FDV1-K.%$aYkS\'8gNCMA0]h:P%,Z+mK$5:Z>:hrlNjA6;\DJ004F^J;OTiNWHa/7-5<2g2(jVlAj$3-FpC;O5q%pbW%\_4E)aqp["fg$h.,VGkW;_Y@N2MG3.3h#PF`tTd$UVU')ck`Qhoa!]t8HPb'\E3mV[.-678[%0^Q;oh)@IH55!I^*/S$3/N5(MDo`'&HNr+1jKja8@\lT,n1LaS!nTS(GWA<"hTd`i;48qrM)5nhe"R\q>UmGNkAd;IMT'"!IZ!?0Yn'u#2b[4L'bd(Q8gXTt_%WR>g8E"D/0jO'>G!.N&2;S+O!X![\4OSGPASo;/u$%6U0QqQ(S,D9U!!2g>MtlcjcK)jGt>[526B.4-&!hkEkTQWF2Y0[G<j(g.u4kSp]Edp$Pi~>endstream +endobj +111 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 92 +>> +stream +GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_H"Zg#ZYSJTP%YGC2U%ZDJ?(_?u0NYeAi<FV8*670]3GC~>endstream +endobj +112 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 636 +>> +stream +Gat$tbAs(+']&?qB1Y4B/.%0RZC.]@cD6B*UoS;[#X`Bh$Y$(7^67hBG1pPC`.0ZaS]B97J_Is<Zg<4s*6T'!j2c!i5m6b*][)5&!BVD--'ZM>,)IO2UJ0<gp+o:F^H^TZ,f1O_9OsCJr&(R.*]M:t8M1;cJg$j*'Q+`'K;GjLltFLuGMq>pElGko1IW.I+p6dY:P8k-@[a+01*c_LRmC+SBj0>"+odRMiOhC"k!/fcG3V;MggpLEK=ArK,8"Rf.gD3#8=iC3[q=sF?go7K7*6cpQo$"d?)MW"SXh`h6(CC,Z-Q/Jb@2>4TDao-mgmIjJbn>7k=n%4dcJuXhS@DE%(`CK@LJr>)MPdmO(KquG&*,R_GuHN?#A)ANRg>JIVloRT%4?SF,dWJ:/@5b958b+IPf#Uo3>A^4P`iNA=VADFqL=G'Rb[A)sDaW__`jh3%GrUe=Dl.4SPM+$D)7J&r0`N#<e^CSU*LCT.:IZH^TBM[lW8eUX&dlDigY6FGE^h6`KG79&V4hS$m-<7=/%7E@chb^8Y;jo/aC&2/?Ji4SJ.qDs-Ga0,So.;;M"h74rAnMZAl!!)f6sc>:Pr7Xjc`=8h46kp>`2RJuZ13U1QYiZqsSjZ;`C3J-/Uq]I0~>endstream +endobj +113 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 92 +>> +stream +GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_H"Zg#ZYSJTP%YGC2U%ZDJ?(_?u0NYeAi<FV8*670]3GC~>endstream +endobj +114 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2494 +>> +stream +Gb!ku9lJcW'#"0Do[,J!)1GN$*!R'(p=^&ZcUNiRi(JuE8\IKs[G=P-rqH;i8LgMeYN]F2#dB+0_'HY)WnsdX<HQ$(r!V:m?8;/&akg;./-spLc%=T+flFnm0$jN>(3E?l^?5_mQEVpb]NI(PYn"7V)/Fa$IWOX?Ck(Tlj1-8;nX&+&ea,&aSWY\s_Di#BI5<J-qd7\K`($sR3#EChf!8c$SA#dn/S%.>VKkIp`,k'pBpcjGo:ja\Ahj!lk?k[Q125Cc<Z,[n/U-p_?eFqAD##T,nu"S2\Mqp_)rKJ+[3KI=R#H%TnQgO4;1Y''Bb3aM\S(*KXahoAru\e;W\J=f<RKmY0Ng3D'go=[RTHeBq@2%bDkZa!'");)T\Cu*fUc?aU*n[bK(6E[>I?\#l+QZDd9;diMSbk@X.OY9Ifm4mX'S&OD@pn<I1pXX$f?G%D@i8gSOdDH^kpNjKr=DY*^`'K25%3@n$KkX>:[tdn\Af3^dFKb0(/I+>J;Qjqp<6&X`O_k*mX4=>X//'f!6!%6L`G`H/7o\Pi:IM%,rCN?k7\,<Ga"1@qs9`_"Nmp-%?Q=V%@8Yc$*B[)ck+Hk5*20i9dkO'HFF_cO.+IG0>,5NYpqjTg&qJc5pH'_M=_upBtRID+=6Y#pYfPq6j>#g.7<sP/jLn=BXTA/_37P#o7;G8UYSHJ*r?+>MbrU.I<6KXNbUom/Fn3$9inq^ukhOStAI!/>,@_:6g-qH8O=NHW_Tn@6`.R(]jcsiS4^T<h`Q?&>ul%)OG$+QV@Kn:W./$m7:3oT"Ve(-Y#SV=:VfA@n#n8,RS.WMb]u>Ff@@f^"02mmQiVZ9Di1h#0po1Y/?7MO-UYQ2*)Q0)*#@0SV\j>rle,XYR`\YO#?=(oW7$%O`21P`<9S3bkJuH<OIA7":rB&^k9+l53rUd\UP.N2<=oS?Z;gege4:hhhe`'-WQ/#:UbOq,J#)*ZVo?#L3h=q`Dn-UbAbG#*O9b1VKnW+IX8(ZXeb<kZrY[>D[.0`3In83Q)lp"F$+V?D!9)Doq#qQ`4FAgK$7u7B?+Ft\K\bE]Q$7H'bNNfX;<ItN]B'Ql&#qhiOa(C8/KV#+,%l0dh#2eRf[h'4q/+W&kF=5E$[o1eV9Tf_ud<@)J+mVf,*M)dY2Ye@hU*ZUH!e8DX*b-jJB4ZXg2t/MHqo(E+"MmQ&O7.J)N:aAMFJ<jU),@7YY\UEEPB9^nN])8s!H2\45SJQZ1`Bl;H2C+F0sONKFAUT7fQm+a$O\HdXRQW-2.,`WbM#Xa>nnUrBLt\N#7/eR7)PAT?J]L]1.*/2Z89;sY!DPWs_SlC+NOcCEe':1^>^Ojo#6!%@\EX0OPK.--BPCGr`nl/NRh8?Ss"M/c\@)Cg]Xq:9%_[\@Zo:].<17tEFK73f#hiD#b,4In'LK:;)Z</3X%d3RFfAl17%A7lRlTc4g8qLH]<o@7@=FB_HFIl*5!pueasM[:H#6P&$/QOmoj4A4B4m;M2"Q'OH,/i6s_nIUEujMN_6:p/Qad8VVqQBJ!pdhQjseDSW4)g%I,As>jmKqf6%VXO8pV1)?V$!V,oCps$sl-$6i/#;FJqp7!"[1Q01SH*\B:boiZ*RFaPc+%.l3q8!oY[jXX(7.h$L<d>S98==;_5e`-.48&DQ:>^/G,_7+\u*m[C#O$M;&1#P6$;b"^\;p[(Dbk0KrLcb!@`]If="RlT6;iY"h,I$6^t75[TC%lG,456'_GRhE9+kQ1n4,JNh3_QcuiX-X:+hPMh[S9KJK\2hj)H`%l[,[ALSZhM9`YF87Y7=;(rC%2/TC<0ReuGTm^V1+dmHd;\tET[:5'n&PPiA$O!<NE/<.MDAr!EM^BP_c<j*0F>A+40Zdp^)4cV&*+OO3Q9mcmMlWp:%8UgOALo%e%.*jugXNHUp#KNH$b&1h=;'9T6n[(Hn&bM<Bf:uS%f`G#Md\aJ6*>N_P(\;=JDA#.U6*Y,JF0Z;)[(^_7a,Z\2h]K>$Yh'YEOEU&f1"HOID,Xhd.RNgkjf\i+UB@FrF0TuZ=VfL##UVm$,b/FeJh#!W^TmH/)nM$%FQLE?,\RnO#uJ#+b*bqD3&(KpE+=p?H:7$le?2fk/X[7(r]qXQQ(!&*\MB7Y79oI_B!gorq7ZqX_Y:Bkkk?)1nl/nSi7`Ec[uHMW5!cAZ?5OJSFm_r7,+6(*6N._rIb'R`Xn*+n9tDkbscK0a#)rcnaGNS'Q'Ob#mk:3"8Cgb?ChN(crR<g\)Y;D6F;@.#GX/H3E76:&()*-d1eWeNd]a=@-0gVJ(@rbC-o*8,XW+!p^V@oBK#_i?[=_U[<Oq\Zl8sedCo<aDTE^/MQ5pgGP&simSW7&-qCTg_)Uj>8+3jW]qq//JLDL+i9^hsom`7"JcB2d>+0uEEBK;g\%_1&355<RMZ$=W7\-Ch1%;T[;/G5"W,tda+[Ger1C=77oSXbYETb0^cb(qs^[UA7qFuH=3Lg=Mdjtm4\"=HWD9gH+%F\E_G5~>endstream +endobj +115 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1176 +>> +stream +Gat%!?ZY3b&:`kAlsoI<;_2>rGj:AI0U\U@%F-5i\JJ\tZ!(YJOpq#mmn/*L(q?>N`\s-igAUtQ;$cZcrgp7nmLm%#;P4G]*,%l08ETE'o`":+rQHr<!KDgG%-%?p#3-9HiGd_1og]N;cn6`cp$5o%^dhof*XTi=.&N)BiFZ+=A)A(qO9Tq5ZEcgK>2UEAV88.=^Noir%LZV'[q./>>c-:K<IOlK\L`FXO;,2c<L&]d)Gmu&jC<Xr<[dX-aIoNKW\9J3$-?7Bd%t+X!BpsVC0=d9d(CuAC7peAc#lYhdh.AmnN)Fo(k'9\#Qj-"f[]pB%L9@9lJHP`nl7,HV/-0,Q!rN%4.h%-6)&mi&NRVsknPOj0!p5`@ZJR-U,&I4\dOQiA0/gu+]>^S$_9mrm[),^j"s$(eb]4/M7,/Us-tXM"tb-5Xdri:),V.PZ(pJ;FEb%M=pj<UlYprq2Y^Q8##&g6=JI]L%k@[Kg/b'0)9UlX<JAet+?G&[0WNO"35irSdXqUBr#EoEONFVS=o:>Lp,0I!*M\@mnKtBJ!j6dd#j^Cm,M;s$Aj%o"D3'XnEPUN-JOZa!)g.8e((h=:'H"[o>/8rq^X'/WEQIB$G#&?ejJg4O:_nap+=q+QEZfuo(lgonbNm=j9N>Z_YsQghhNM#?K5^+.<FV9sM8R`T4'^q)'-aOL]%)eED=&aNd/?$uT[DNMs%I0i>,>H]=F2>l@18UYlblM&gs9ork=;Yk.`e)/FnJ#%(&"3(KiMWDG\/4W(`gsj$Ya&?nc2J3#u"\I*ane+:#=YAB0`r4)p,<KBo.sW,O4(ON/S7\S`%acXn<m%'oJ>j.(3W6BlQ>\H&k]:o2A0J3sBH*aVD&>g@`ao&N&Vg9h+0j:KV/kn/l`HQpZe'_ThDt&_ZtK<b^5tBP]6Cm!8!1\R5cpPSk0_,>cL]O;ik'G7bf'PEKPrMI<FfP2!(B>+"b.mN2I$_>tZc"V0#$1qZ5>E?4e/$8PGD)#O;Xn]0\=N&Vd`@)eJ;IAffT0eke1/5Ika)^-b4DR[]0+!$IVTS"A=RHE^pa[T6hJ8_Z.d.;e$m5UH%-aho6p#1?$BOE[NlZ1DYf?,@^M4aP"X3(3#@1_iSN.N3]'T)_';9mIXj>Uu\\*iJVFFO400qiJLlpUA_8;I4p^[NL.o_o"<IU+T~>endstream +endobj +116 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2694 +>> +stream +Gb!;f>B?:T&q9SYkXR!H'4sL7p>qN;H]iN:2t86K8o9i#&.I"*#da\9f"^,1!FZ,:5q8KiG+=_+dgX_(p"-Yb!u$0OILT?Y+(t*%'*H6_('ClP)eR^khq?]?B<7E+9uCL?G7(M5)P6'FGTU6M4K/7/qg<!XYW4LegG_.Z^T#1T$5\Y%Re!GoD4:R>K+d\DrRi:&&FP'+S$MP3C^&%\pM8P&#NjCa%*#3R%gI6fCJVdN*7ORs>T_7@c,+KIdK3A`7&s])o.:YLYnHM5p(M',8Y&*<U\ZHC;o<thPrRXnKM$?C<-%2n<19PP#?:Q)$jt(B=d_ZsKaS+ta;D't3Thmu+;GhDF.rRh6:5WJ)P/;6pjOGqlAK>,S_KOcD0XB@*:PJJ[dRn_KIkPWJ=4CkYK\7N^LaR[e*Z/bml`P="W(2KSo<"@r$+Kn(n%``6\HK+p?4:6'YiP_#U+cO(n>s.[:$GBp[[:,?12X.!1a(TD4ntknF1^kj[C4?\M!M4+&t<[@():[a>?T58E;JNMBtU_G:CGA]EhJfQO9!HAQ[#)V$57J+j<uf+H7M+WIT>hEk7!TfGVN$XduXN<'`V\,0f5_5^d+86lHD7"bfc.8;s--4Q.'95D6Vg:-j;``r?Wo`\:*>.-EZfJ6mqs)J@X=3>+b''7lB@j%Q.\2&>eb/>*2ok8WU[>(eYs+[k<rL*H(I"(I0VDKuVC6)m'R<sDoL>o)HTF/K,-3S#.gbX*=$#N_Hh1"4?k#.Wb\mR!=26G]:nI"72ET%<Zs48b8Ll9X.sJKRI/a"fpbp1+Kk[6haRF>4j"WB5X:FV<""G!nM*BFW_d*Re`Cffk^4Zp'(cBspU\R+XS6WuOq?nPitg@774Q@[;lXX:l0gaS.HV2-jp!@qmdV@=%`p\]BcLUD"I]HQ0e9#;F1'.]aano,?+*"D^?E8i0B`[hA-c4BmZbS+OmjYOLTCgUG?ZZbIo]e*l2o]Xdk7D)U5oXJ'$=RKe7qA^'>,CTTC(2k`Q3:qb*KD"0:RGY>4b**5A8or&1%W^=_b@1Og@g?#5\8I-`+aB3(UEWYW(Gos*dAmM=fm"ke(h$C[UpjGhD%\cK,M\5e5dV5&?*U"CI\fB6o`(DQ).[g/6n\U[?EjcuW7l.9,^gR8e*q[N'e9+K'32X`E*CHu=fOcG.18S/.6U0@8I40-A9Ko/s-7]Dn`C5NlKCkT?9OIG&D4II?9XYU_9AMFtBuk&A7,5o7UgH\k*"D&P(;rAIGo7n&OkPb$7ef"<#&H+E^mm@BkP[H\`Wk+kLRIjMF\:ci<:P1ULcA%c*$\6c.#I0nWu.BkT'8'YFd#*T;:dbJ2KBm5Mb+IXObmk6GCF-fO.5N`D\P,Hn+/Co:W3d$b6eE1?C:8pn.DI5@O=CP."d6;K19!6C8g1(IESmgaB%"FU3`,VnDE/5htIp+%AiI`!@U,&NC);pco#1!K'Pr%YauZOYn:m"Z.$a2!qT;n1%4hlGegs8mb+aO^VUWPUPPoBR[5dd3lu(qQ.W1?e1oYK!giC]2RV6FFY@$0)6cRApIM8tQ=m$$Yu=K8,@!H+9U4*Iib.d(_Qpu<..j6lXLW6q2L(#(M7,4-$+@(;l]70Be7Pf0rA4PupD\[m`F6(lM@WC#*39`cMW9Yiq308gm?l5jQJumC'$)m_YU74Hh&GgBATSl^_ZHd1o*QB6m-L-tmA&giQL2)e4Jmh58\GQ#Od6=@@nR>lpA6m]A6N!^+qujJX`dc)%IK='/f$4=ZN46%#76jJ;P9XY2Fp>Wf!9Rrb_ZCefa,6&cAkPrmC)D?fQ:?)#umZ>$H:Zk;+(jJg+G(c''T\"=9M'l"O5,j3I%OWIJ7up[Hr39JGV!AGkJgZ>Pi4a_N$1het^=*?,*5c$09g`Qr2Cjef2s`C/jN!?Kji5,t>qm%;1i8GPKnu2K@>`G(66:_]"*Xbbdblc#BV=Ac0JtpS%G+GQ,-g,4qhqi(U]c-M^qR(I`K"9B6L\\<M[QM4LDEfZ)sUJ8Mum_ep1VYR^Gj_VhW/b3cb'aMNm?mXPq&!Z3KF[TdeGJo8+IAL)F(SaA+/4'e4B]f(/Kb;"JH%+BX*@(=G=.-@'[ZQO>4Zk+^a=jUCf)hGCpG6$JgX#eA(q:%LQ*06"<5SCG#.hiscPW)=o*',Wc`J$!=F7_:Xd@og[F\g_Z-tBB1Z9QO>3eGuJ/SNIif@B\E07&]bmkoRM+t,b+V7GfMW^GQJ>UD;&-'PgeAs/5C(s*j(9KFG,T>ZG5qr$t25ldh:b1042l_kt#!_);C_/<MUCJ1W\04JFh7rHl)mq+#dAab.u0)D?8[Y+3al/XFkWR42oYQ/_LZfDdT%-EfOCi:^g&HI7I^u9KCEmp]jR0ZI3D&TKd87+]o_j@n@e.urJJ%`S1I951hlh:p[9#BIsW3SOD$htmo.,3qffkS?Oj6TgmQcO^`ZM@:t.I+mTAQh8k7_:l(o'RY%?`+7SI=%rDc9Y_KF81ULBk`oe<7Z92IbQT[-u#cJ^fS%Y\N2_U[-dh1[u_X7Nh??>VX%%4Y.gC@FWEWd@81+A+t$0e+Y@_XT`R7mUMk((fZiW2hgq2BPsR!:<8h'-5k)417n8jV#P<>Q8E("N0h!3`FSaQV0j(WC3\4!s)bu@MK4>?npB^lDXp$r3d@<7ZUT<qF^N/!i'H:`+FkO*g++EF\ZT+KR""2]263~>endstream +endobj +117 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 822 +>> +stream +Gb!;`bAQ&g&A7ljp?2\e,>o%U\J,M$"9EOV$N[s%6;*Q]ee/XYWggclP*TW?G*Dc)bE.895%]SV9-M*+qKLcr>\A#$97\k>8tZcQ+FAXbg$EuR#L=e@!KD@5SAul\dg4uGJNrM$fbbh+G]jXh^d[GgT(bS8KE<BeK+'RZ0qMq[bTA:s+!CF]fbn%2m9&C!52/+LS-g;!hdkPD)54k$ee3r0]3I\%<YBeZbM-QHS?#,XQILP4N1Z_p$S6DV2mTisJ59P?U!t+<e_4,hGO!::X"=SZ!cB&#aOnB5Hlr>bP)h]CHu_3'e2bBE-+rF_6mn\VWia'Ok`#`$Y$QKK]D/F%4Oko?YYrY>F>$]#4WFJmha@F86^[ih+sUgcIV9u7=0Dd"6]reAO%-8TEa53,,Y#&g^%KubCtIjY`tZ,WL-^@;.)=Yc)Qr827R=Bb-u2)A6G$.Vdep]aGAcBL6]_j;W=UN2r4h(48-j!A-V=IFq]F,sdYjN&()%HPa=)-%8[ptUFnXM*,KEmF^5fH8(R/]p:_lPM&=,!k`B_9ci/>ZTpq7HoWVlaX1"O.O;qB'<S5`p^DEkk=j+Qm0[ti*lBFr$)ArK*cIcEW\\'l[^%1o$q;&$q/m9HB<CI%l"jq+^l@VX`&$HP(CF,NDD1CL_&i's,>GBd#D[ZrAE0X_cWFFM,-k+[sPn.<(^b2lu=*P\eX?593ZjZ/d`T>mS1Le<!?]"Qf'cS\,MJ>NYGNNLfJ;Jj76>W7l(VY*<Q]uffI6Pp7BMguI1=`XA9],Bgb:5bhY:U'KGXc\*%2&/PG-Ce"`HI:eREgZe+h7h,/~>endstream +endobj +118 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1470 +>> +stream +Gb!#Z9lo;R&A@ZcqFIob=Rm9PSsW5C9l4K$)48R#Mm6ipNGWql)j:$igQI-?"S/fTLCL686rJ6Df<;eT_86^?J&;]Qo,KB['I\TZ%+HF1b\uEShYY]qgRX?n/F*'apmt8Np=R3&\4fB=r-l9G&K<Vk13UYQKC5L>ol:mID96?A@?*]@5G@0-q7Lp,L+i\?&'DngGm8AlT/RT*"7#-t#\C.p#/WLb4"_*!Zi#r<p7Zt?ElIX3K?U#]38D\4NSn,2pr\q90`MC?k8Mg?nb3Z_m1S_di*prr">7B`EI%D[EOeX6)n<$aW@AXKU8Sid0a3EX3#'2d^B9\M`akKKN4BUc%NoPmDjfr2b),HL5j"P2!0@<jK'*E"Et''c-'7W'M!GaC*m6;H.Y2qH*@?:`oU4t)%Mo"Waa_f&YL4ecW!=C20NlEg?-SWuW"s$<hF?gjqua=E[HQ8<0/0_BOSbNlL9-u_P#,cZE,,9gq$"(/a2C%c)lhLRWgcR*QQ0lTcHO'A^f;E[KrWUpi_a>3aRT/h']$gBe2=Uch2c)KB:'a(^:24'7s:A\Z)rLpK<>K>g!WhUln9Tb2Z8Ydj7@oW2^Q<H*APSm$DcE'YY3SCa#f5_nA)F_2`sW.GVY#2LIj,8+GC:*#hFPtK4TqW?1Y@a/mf)bUL@=r,%$af)4Y".@!gSu"ZJ`]Wa#./Zq?0ND0sKcDSPRpKWd[J@i1.'4:u--=-:j\/C*rQ)BePHC!S0TG%b=3^Ufsfc<tCe%;#bS7>r3'i.tFuVqo5D$(kY_4Q#l)qo.(<14@;(I*!mFL'\L?Yje0QD'31>P,@YS6)HO69N>]';?s];bYK7OKV_pgW0`!W%m;k5:h&]YY)XGLU,WP'#G_<iYtKWg-V[GY78O1+8"9omQ9d%:GEdes&at3/>5lOcPfPpq'I_C81V^\S#:.lToT@6^$*udr'U,/mH6C:H(r9,$'ssm!;!lCg2KB#+6n<SjCiKC;dA0H:osd>ZMY5q=q2TY&?C<qo>1TOB@cegH.]eo<'h&*]).+>SVSe0oDK(2ID%Cm*&iofe,fBb$R)-3un.%lHT%B_*8H0Xg:,]t<qK`7^Y+e2'\Cq(a$[aU"\OK=jca2Ss=YknU$+O4EH1`uo/e$M4Z,$7"!a1,rMH'(9(YXEp,blj.ZI[!%k7Jb.7EBQ#m<jSuNor?\YMo'Z>ulKH3Ks\N*^D%slpYRkh6i75a,je[0h^8Gn/;kf<?b*+F73%?!/\sbl0J`-kV`dr1llN./loGmg/oG\e*PT;D-oZW`6j$q<)oVU?!QTO5YtK*k)]C45c`?X#h)kl$7="MQu,tF?tTni!2sbFE31REadVBMLEXlV;/p!02<[[&0=_QB3Ij=@J>M_E"8GW'A:dj2UPliRh8Pd<B#F/[UBB=N+g+J%_\T$Y9!5kDG.&>ZQ;8?/hJ4Ecr8R>jYMOWPf[i7CVuF_"qZk-7pFj*8DA`~>endstream +endobj +119 0 obj +<< +/Nums [ 0 120 0 R 1 121 0 R 2 122 0 R 3 123 0 R 4 124 0 R + 5 125 0 R 6 126 0 R 7 127 0 R 8 128 0 R 9 129 0 R + 10 130 0 R ] +>> +endobj +120 0 obj +<< +/S /D /St 1 +>> +endobj +121 0 obj +<< +/S /D /St 2 +>> +endobj +122 0 obj +<< +/S /r /St 1 +>> +endobj +123 0 obj +<< +/S /r /St 2 +>> +endobj +124 0 obj +<< +/S /D /St 1 +>> +endobj +125 0 obj +<< +/S /D /St 2 +>> +endobj +126 0 obj +<< +/S /D /St 3 +>> +endobj +127 0 obj +<< +/S /D /St 4 +>> +endobj +128 0 obj +<< +/S /D /St 5 +>> +endobj +129 0 obj +<< +/S /D /St 6 +>> +endobj +130 0 obj +<< +/S /D /St 7 +>> +endobj +xref +0 131 +0000000000 65535 f +0000000073 00000 n +0000000158 00000 n +0000000265 00000 n +0000000377 00000 n +0000000584 00000 n +0000000791 00000 n +0000000959 00000 n +0000001127 00000 n +0000001295 00000 n +0000001463 00000 n +0000001632 00000 n +0000001801 00000 n +0000001970 00000 n +0000002139 00000 n +0000002308 00000 n +0000002477 00000 n +0000002646 00000 n +0000002815 00000 n +0000002984 00000 n +0000003153 00000 n +0000003322 00000 n +0000003491 00000 n +0000003660 00000 n +0000003829 00000 n +0000003998 00000 n +0000004167 00000 n +0000004336 00000 n +0000004505 00000 n +0000004674 00000 n +0000004843 00000 n +0000004959 00000 n +0000005128 00000 n +0000005297 00000 n +0000005466 00000 n +0000005635 00000 n +0000005804 00000 n +0000005973 00000 n +0000006142 00000 n +0000006311 00000 n +0000006480 00000 n +0000006649 00000 n +0000006818 00000 n +0000006987 00000 n +0000007156 00000 n +0000007325 00000 n +0000007816 00000 n +0000008024 00000 n +0000008135 00000 n +0000008343 00000 n +0000008551 00000 n +0000008671 00000 n +0000008859 00000 n +0000009053 00000 n +0000009247 00000 n +0000009419 00000 n +0000009607 00000 n +0000009801 00000 n +0000009995 00000 n +0000010167 00000 n +0000010355 00000 n +0000010638 00000 n +0000010832 00000 n +0000011026 00000 n +0000011198 00000 n +0000011386 00000 n +0000011596 00000 n +0000011768 00000 n +0000012030 00000 n +0000012136 00000 n +0000012317 00000 n +0000012528 00000 n +0000012725 00000 n +0000012936 00000 n +0000013184 00000 n +0000013364 00000 n +0000013591 00000 n +0000013771 00000 n +0000013981 00000 n +0000014191 00000 n +0000014411 00000 n +0000014631 00000 n +0000014849 00000 n +0000015071 00000 n +0000015247 00000 n +0000015523 00000 n +0000015631 00000 n +0000015889 00000 n +0000015964 00000 n +0000016103 00000 n +0000016264 00000 n +0000016377 00000 n +0000016500 00000 n +0000016623 00000 n +0000016746 00000 n +0000016869 00000 n +0000016991 00000 n +0000017172 00000 n +0000017314 00000 n +0000017459 00000 n +0000017602 00000 n +0000017763 00000 n +0000017908 00000 n +0000018049 00000 n +0000018223 00000 n +0000018354 00000 n +0000018547 00000 n +0000018677 00000 n +0000018811 00000 n +0000019307 00000 n +0000019490 00000 n +0000020502 00000 n +0000020685 00000 n +0000021413 00000 n +0000021596 00000 n +0000024183 00000 n +0000025452 00000 n +0000028239 00000 n +0000029153 00000 n +0000030716 00000 n +0000030866 00000 n +0000030901 00000 n +0000030936 00000 n +0000030971 00000 n +0000031006 00000 n +0000031041 00000 n +0000031076 00000 n +0000031111 00000 n +0000031146 00000 n +0000031181 00000 n +0000031216 00000 n +trailer +<< +/ID +[<2db82f8d13fc9aad0f6ac8c1445975f3><2db82f8d13fc9aad0f6ac8c1445975f3>] +% ReportLab generated PDF document -- digest (http://www.reportlab.com) + +/Info 86 0 R +/Root 85 0 R +/Size 131 +>> +startxref +31251 +%%EOF diff --git a/doc/History9.htm b/doc/History9.htm deleted file mode 100644 index 4ebca7b4..00000000 --- a/doc/History9.htm +++ /dev/null @@ -1,201 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>History of Ghostscript versions 9.n</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<!-- -WARNING: do not use Pete Kaiser's emacs function "gs-toc" alone to -re-create the table of contents here, because it will replace the -hand-edited TOC subheads with a separate subhead for each H2 in -the body of the file. Or if you do, first look at the original -TOC to see how to edit it for visual conciseness. ---> - -<h2><a name="toc"></a>Table of contents</h2> - -<blockquote><ul class="toc"> -<li><a href="#Version9.56.0">Version 9.56.0 (2022-02-22)</a></li> -</ul></blockquote> - -<h1>History of Ghostscript versions 9.n</h1> - - -<ul> - <li>Version 9.56.0 (2022-03-14)</li> -</ul> - - - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - - -<p> -This document is a record of changes in Ghostscript releases numbered 9.xx. -<p><u>Important</u>: see <a href="#9.56.0_changelog">Version 9.56.0 Changelog</a> - - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> -<h2><a name="Version9.56.0"></a>Version 9.56.0 (2022-02-22)</h2> -<p> Highlights in this release include: -<ul> -<li> -<p><b>New PDF Interpreter:</b> This is an entirely new implementation written in C (rather than -PostScript, as before). For a full discussion of this change and reasons for it see: -<a href="https://ghostscript.com/pdfi.html">Changes Coming to the PDF Interpreter</a>. -<p>In this (9.56.0) release, the new PDF interpreter is now <em><u>ENABLED</u></em> by default -in Ghostscript, but the old PDF interpreter can be used as a fallback by specifying -<code>-dNEWPDF=false</code>. We've provided this so users that encounter issues with the new -interpreter can keep working while we iron out those issues, the option will not be available in -the long term. -<p>This also allows us to offer a new executable (<code>gpdf</code>, or <code>gpdfwin??.exe</code> -on Windows) which is <i>purely</i> for PDF input. For this release, those new binaries are not included -in the "install" make targets, nor in the Windows installers. -</li> -<li> -<p>Calling Ghostscript via the GS API is now thread safe. The one limitation is that the X11 devices for -Unix-like systems (x11, x11alpha, x11cmyk, x11cmyk2, x11cmyk4, x11cmyk8, x11gray2, x11gray4 and x11mono) -cannot be made thread safe, due to their interaction with the X11 server, those devices have been modified -to only allow one instance in an executable. -</li> -<li> -<p>The <code>PSD</code> output device now writes ICC profiles to their output files, for improved -color fidelity. -</li> -<li> -<p>Our efforts in code hygiene and maintainability continue. -</li> -<li> -<p>The usual round of bug fixes, compatibility changes, and incremental improvements. -</li> -<li> -<p>(9.53.0) We have added the capability to build with the Tesseract OCR engine. In such -a build, new devices are available (pdfocr8/pdfocr24/pdfocr32) which render the -output file to an image, OCR that image, and output the image "wrapped" up as a -PDF file, with the OCR generated text information included as "invisible" text -(in PDF terms, text rendering mode 3). -<p>Mainly due to time constraints, we only support including Tesseract from -source included in our release packages, and not linking to Tesseract/Leptonica -shared libraries. Whether we add this capability will be largely dependent on -community demand for the feature. -<p>See <a href="https://www.ghostscript.com/ocr.html">Enabling OCR</a> for more details. -</li> -</ul> -<p>For a list of open issues, or to report problems, -please visit <a href="http://bugs.ghostscript.com/">bugs.ghostscript.com</a>. -<h3><a name="9.55.0_Incompatible_changes"></a>Incompatible changes</h3> -<h4>Included below are incompatible changes from recent releases (the -specific release in question is listed in parentheses). We include these, -for now, as we are aware that not everyone upgrades with every release.</h4> -<ul> -<li> -<p>(9.55.0) Changes to the <code>device API</code>. This will affect developers and maintainers of -Ghostscript devices. Firstly, and most importantly, the way device-specific "procs" are specified has -been rewritten to make it (we think!) clearer and less confusing. See -<a href="Drivers.htm">The Interface between Ghostscript and Device Drivers</a> and -<a href="https://www.notion.so/artifexsoftware/The-Great-Device-Rework-Of-2021-94092fe1395d4a088b91462f0ca5038a">The Great Device Rework Of 2021</a> -for more details. -</li> -<li> -<p>(9.55.0) The command line options <code>-sGraphicsICCProfile=___</code>, <code>-dGraphicsIntent=#</code>, <code>-dGraphicsBlackPt=#</code>, -<code>-dGraphicsKPreserve=#</code> have been changed to <code>-sVectorICCProfile=___</code>, <code>-dVectorIntent=#</code>, <code>-dVectorBlackPt=#</code>, -<code>-dVectorKPreserve=#</code>. -</li> -<li> -<p>(9.53.0) As of 9.53.0, we have (re-)introduced the patch level to the version number, -this helps facilitate a revised policy on handling security-related issues. -<p><strong>Note for GSView Users: </strong>The patch level addition breaks GSView 5 (it is -hardcoded to check for versions <code>704-999</code>. It is possible, but not guaranteed that -a GSView update might be forthcoming to resolve this. -</li> -<li> -<p>(9.52) <code>-dALLOWPSTRANSPARENCY</code>: The transparency compositor (and related -features), whilst we are improving it, remains sensitive to being driven correctly, and -incorrect use can have unexpected/undefined results. Hence, as part of improving security, -we limited access to these operators, originally using the <code>-dSAFER</code> feature. -As we made "SAFER" the default mode, that became unacceptable, hence the new option -<code>-dALLOWPSTRANSPARENCY</code> which enables access to the operators. -</li> -<li> -<p>(9.50) There are a couple of subtle incompatibilities between the old and new SAFER -implementations. Firstly, as mentioned in the 9.50 release notes, SAFER now leaves -standard PostScript functionality unchanged (except for the file access limitations). -Secondly, the interaction with <code>save</code>/<code>restore</code> operations -has changed. See <a href="Use.htm#Safer">SAFER</a>. -<p><strong>Important Note for Windows Users</strong>: -<br> -The file/path pattern matching is case-sensitive, even on Windows. This is a -change in behaviour compared to the old code which, on Windows, was case -<i>in</i>sensitive. This is in recognition of changes in Windows behaviour, -in that it now supports (although does not enforce) case sensitivity. -</li> -<li> -<p>(9.27) The process of "tidying" the PostScript namespace should have removed -only non-standard and undocumented operators. Nevertheless, it is possible that -any integrations or utilities that rely on those non-standard and undocumented -operators may stop working or may change behaviour. -<p>If you encounter such a case, please contact us (<a href="https://discord.gg/H9GXKwyPvY">Discord<a>, -<a href="https://web.libera.chat/#ghostscript">#ghostscript IRC channel</a>, -or the gs-devel mailing list would be best), and we'll work with you to either find an -alternative solution or return the previous functionality, if there is genuinely no other -option. -</li> -</ul> -<h3><a name="9.56.0_changelog"></a>Changelog</h3> -<p>From 9.55.0 onwards, in recognition of how unwieldy very large HTML files can become -(History9.html had reached 8.1Mb!), we intend to only include the summary highlights (above). -<p>For anyone wanting the full details of the changes in -a release, we ask them to look at the history in our public git repository: -<a href="https://git.ghostscript.com/?p=ghostpdl.git;a=shortlog;h=refs/tags/ghostpdl-9.56.0">ghostpdl-9.56.0</a> log. -<p>If this change does not draw negative feedback, History?.htm file(s) will be removed from the release archives. -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/HowToBuildTheDocs.txt b/doc/HowToBuildTheDocs.txt new file mode 100644 index 00000000..26c89d23 --- /dev/null +++ b/doc/HowToBuildTheDocs.txt @@ -0,0 +1,100 @@ +How to build the Ghostscript documentation +========================================== + + +Welcome to the Ghostscript documentation. This documentation relies on Sphinx (https://www.sphinx-doc.org/en/master/) to publish HTML & PDF docs from markdown files written with restructured text / RST (https://en.wikipedia.org/wiki/ReStructuredText). + + +Installing Sphinx & dependencies +-------------------------------- + +1. You should follow the instructions on the Sphinx website to install Sphinx on your system. + +2. Ensure you have rst2pdf (https://pypi.org/project/rst2pdf/) installed: + + pip install rst2pdf + + This ensures that you can build a PDF of the documentation. + +3. The Sphinx documentation files also rely on the "readthedocs" theme to be installed, follow the instructions here: https://sphinx-rtd-theme.readthedocs.io/en/stable/installing.html + +4. Once you have installed the "readthedocs" theme, depending on your OS, it will also have installed a `docutils` (http://docutils.sourceforge.net/) Python package. + + This should be okay, however if you have issues with building docs for PDF ensure that the `docutils` version works for you. + + To see what version you have do: + + python3 -m pip show docutils + + On Windows the required version was 0.18.1 to build PDF docs (pip install docutils=0.18.1), however on other systems lower versions were fine. + + + +Editing the documentation +------------------------- + +Within this `src` folder update the associated `.rst` files which are in restructured text format. These files represent the corresponding document pages. + + +Some notes on syntax +~~~~~~~~~~~~~~~~~~~~ + +- Use ``for inline code`` or ``computer/technical terminology`` + +- Use tab indented code for code blocks with, e.g. .. code-block:: bash + +- For device names use :title:`deviceName` , e.g. :title:`pdfwrite` + +- For headers underline text with ==== for h1 level, ---- for h2, ~~~~ for h3 & """" for h4 + + +For full details on RST syntax, see: https://www.sphinx-doc.org/en/master/usage/restructuredtext/ + + + +Building HTML documentation +--------------------------- + +From the `doc` location run: + + +sphinx-build -b html src build + + +This then creates the HTML documentation within `doc/build` for your review, you can then run `build/index.html` to check out the results. + + +Building PDF documentation +-------------------------- + +From the `doc` location run: + + +sphinx-build -b pdf src . + + +This will then generate a single PDF for all of the documentation within `doc`. + + + +Updating the documentation +-------------------------- + +- Make your edits as required in the relevant RST files ( see above: Editing the documentation ) + +- Test locally by building and running in local browser ( see above "Building HTML documentation" ) + +- Ensure to update the version of Ghostscript cited in `conf.py` line 52 ( e.g. release = "10.0.0" ) + +- Ensure that News.htm reflects the latest release and had any further "news" + +- Once changes are pushed to golden master then readthedocs.io should pick up the changes, build & deploy the docs! + +- Visit ghostscript.readthedocs.io once built and deployed to check + + + +--- + + +For more see: Using Sphinx (https://www.sphinx-doc.org/en/master/usage/index.html) diff --git a/doc/Install.htm b/doc/Install.htm deleted file mode 100644 index 8a63c019..00000000 --- a/doc/Install.htm +++ /dev/null @@ -1,419 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>How to Install Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>How to Install Ghostscript</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - - <li><a href="#Overview">Overview of how to install Ghostscript</a></li> - <li><a href="#Install_Unix">Installing Ghostscript on Unix</a></li> - <li> - <ul> - <li><a href="#Shared_object">Ghostscript as a shared object</a></li> - <li><a href="#Install_Linux">Additional notes on Linux</a></li> - </ul> - </li> - <li><a href="#Install_Windows">Installing Ghostscript on MS Windows</a></li> - <li><a href="#Install_VMS">Installing Ghostscript on OpenVMS</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a> and "<a href="Make.htm">How to build Ghostscript from source - code</a>".</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Overview"></a>Overview of how to install Ghostscript</h2> - -<p> - You must have three things to run Ghostscript:</p> -<ol> -<li>The Ghostscript executable file; on some operating -systems, more than one file is required. These are entirely -platform-specific. See below for details.</li> - -<li>Initialization files that Ghostscript reads in when it -starts up; these are the same on all platforms.</li> - -<li> -<ul> -<li><code>gs_</code>*<code>.ps</code> unless Ghostscript was compiled -using the "compiled initialization files" option. See the documentation of -<a href="Psfiles.htm">PostScript files distributed with Ghostscript</a>.</li> - -<li><code>pdf_</code>*<code>.ps</code> if Ghostscript was compiled -with the ability to interpret Adobe Portable Document Format (PDF) files, -that is, <code>pdf.dev</code> was included in -<code>FEATURE_DEVS</code> when Ghostscript was built.</li> - -<li><code>Fontmap</code> and <code>Fontmap.GS</code> (or the -appropriate <code>Fontmap.</code><em>xxx</em> for your platform), unless -you plan always to invoke Ghostscript with the <a -href="Use.htm#FONTMAP_switch"><code>-dNOFONTMAP</code> switch</a>.</li> -</ul> -</li> - -<li>Fonts, for rendering text. These are platform-independent, -but if you already have fonts of the right kind on your platform, -you may be able to use those. See below for details. Also see the -<a href="Fonts.htm">documentation on fonts</a>.</li> -</ol> - -<p> -The <a href="Use.htm">usage documentation</a> describes the search -algorithms used to find initialization files and font files. The -per-platform descriptions that follow tell you where to install these -files.</p> - -<hr> - -<h2><a name="Install_Unix"></a>Installing Ghostscript on Unix</h2> - -<p> -Ghostscript uses the common configure, build and install method common -to many modern software packages. In general the following with suffice - to build ghostscript:</p> -<blockquote><code> - ./configure<br> - make -</code></blockquote> -and then it may be installed in the default location with: -<blockquote><b> - <code>make install</code> -</b></blockquote> -<p>This last command may need to be performed with super user privileges.</p> - -<p> -You can set the installation directory by adding <code>--prefix=<em>path</em></code> -to the configure invocation in the first step. The default prefix is <code>/usr/local</code>, -which is to say the <tt>gs</tt> executable is installed as <code>/usr/local/bin/gs</code>.</p> - -<p>A list of similar configuration options is available via <code>./configure --help</code></p> - -<p> -For more detailed information on building Ghostscript see -<a href="Make.htm#Unix_build">how to build Ghostscript on Unix</a> in -the documentation on building Ghostscript, especially regarding information -on using the older <a href="Make.htm#UNIX_makefile">hand edited makefile</a> -approach. Whatever configuration method you use, execute "<code>make -install</code>" to install the executable and all the required and - ancillary files after the build is complete.</p> - -<h3><a name="Use_Acrobat_fonts_Unix"></a>Fonts</h3> - -<p> -The makefile installs all the files except fonts under the directory -defined in the makefile as <code>prefix</code>. Fonts need to be -installed separately. The fonts should be installed in -<code><em>{prefix}</em>/share/ghostscript/fonts</code>. -(That is, <code>/usr/local/share/ghostscript/fonts/</code> if you used the default -configuration above.)</p> - -<p> -If you have Adobe Acrobat installed, you can use the Acrobat fonts -in place of the ones distributed with with Ghostscript by adding the -Acrobat fonts directory to -<code>GS_FONTPATH</code> and removing these fonts from - <code>Fontmap.GS</code>:</p> - -<blockquote> -Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique, Helvetica, -Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique, Symbol, Times-Bold, -Times-BoldItalic, Times-Italic, Times-Roman, ZapfDingbats -</blockquote> - -<p> -Similarly, you can have ghostscript use other fonts on your system by adding -entries to the fontmap or adding the directories to the GS_FONTMAP environment -variable. See the <a href="Use.htm#Font_lookup">usage documentation</a> for more -information.</p> -<p>For example, many linux distributions place fonts under <code>/usr/share/fonts</code>.</p> - -<h3><a name="Shared_object"></a>Ghostscript as a shared object</h3> -<p>If you've built Ghostscript as a shared object, instead of '<code>make install</code>', -you must use '<code>make soinstall</code>'. -See <a href="Make.htm#Shared_object">how to build Ghostscript -as a shared object</a> for more details.</p> - -<h3><a name="Install_Linux"></a>Additional notes on Linux</h3> - -<p> -For Linux, you may be able to install or upgrade Ghostscript from - precompiled <a href="http://www.rpm.org">RPM</a> files using:</p> - -<blockquote><code> -rpm -U ghostscript-N.NN-1.i386.rpm<br> -rpm -U ghostscript-fonts-N.NN-1.noarch.rpm -</code></blockquote> - -<p> -However, please note that we do not create RPMs for Ghostscript, and we take -no responsibility for RPMs created by others.</p> - -<hr> - -<h2><a name="Install_Windows"></a>Installing Ghostscript on MS Windows</h2> - -<p> -We usually distribute Ghostscript releases for Windows as a binary installer, - for the convenience of most users.</p> - -<h3><a name="Windows16"></a>Windows 3.1 (16-bit)</h3> -<p> - The last version to run on 16-bit Windows 3.1 was Ghostscript 4.03.</p> - -<h3><a name="Windows32"></a>Windows 95, 98, Me</h3> -<p> -The last version to be available as a binary for Windows 95/98/Me was 8.60. Although -building from source with Visual Studio 2003 should produce a working binary for those -versions.</p> - -<h3><a name="Windows32"></a>Windows NT4, 2000, XP, 2003 or Vista (32-bit)</h3> -<p> -The installer is normally named -<code>gs###w32.exe</code>, -where ### is the release number (e.g., 871 for Ghostscript 8.71, - 910 for Ghostscript 9.10).</p> - -<h3><a name="Windows64"></a>Windows XP x64 edition, 2003 or Vista (64-bit)</h3> -<p> -The x64 installer is normally named -<code>gs###w64.exe</code> -This is for 64-bit Windows operating systems based on the x64 instruction set. -Do not use this on 64-bit processors running 32-bit Windows.</p> - -<h3><a name="Windows4"></a>Installing</h3> -<p> - To install Ghostscript on Windows, you should run the installer executable.</p> - -<p>The installer is NSIS-based (see also <a href="Release.htm">Release.htm</a>) and -supports a few standard NSIS options: <code>/NCRC</code> disables the CRC check, -<code>/S</code> runs the installer or uninstaller silently, <code>/D</code> -sets the default installation directory (It must be the last parameter -used in the command line and must not contain any quotes, even if the path -contains spaces. Only absolute paths are supported).</p> - -<h3><a name="General_Windows"></a>General Windows configuration</h3> - -<p> -The installer includes files in these subdirectories:</p> - -<blockquote><code> -gs<em>#.##</em>\bin -<br>gs<em>#.##</em>\examples -<br>gs<em>#.##</em>\lib -<br>gs<em>#.##</em>\doc -<br>gs<em>#.##</em>\Resource -<br>fonts -</code></blockquote> - -<p> -The actual executable files for the 32-bit Windows install, in the <code>gs<em>#.##</em>\bin</code> -subdirectory, are:</p> - -<blockquote><table> -<tr><td><code>GSWIN32C.EXE</code></td> - - <td>Ghostscript as a 32-bit Windows command line program. - This is usually the preferred executable.</td></tr> -<tr><td><code>GSWIN32.EXE</code></td> - - <td>32-bit Ghostscript using its own window for commands</td></tr> -<tr><td><code>GSDLL32.DLL</code></td> - - <td>32-bit dynamic link library containing most of Ghostscript's functionality</td></tr> -</table></blockquote> - -<p> -For the 64-bit Windows install, also in the <code>gs<em>#.##</em>\bin</code> - subdirectory, they are:</p> - -<blockquote><table> -<tr><td><code>GSWIN64C.EXE</code></td> - - <td>Ghostscript as a 64-bit Windows command line program. - This is usually the preferred executable.</td></tr> -<tr><td><code>GSWIN64.EXE</code></td> - - <td>64-bit Ghostscript using its own window for commands</td></tr> -<tr><td><code>GSDLL64.DLL</code></td> - - <td>64-bit dynamic link library containing most of Ghostscript's functionality</td></tr> -</table></blockquote> - -<p> -For printer devices, the default output is the default printer. This can be modified as follows:</p> - -<blockquote> -<dl> -<dt><code>-sOutputFile="%printer%printer name"</code> -<dd>Output to the named printer. If your printer is named "HP DeskJet 500" - then you would use <code>-sOutputFile="%printer%HP DeskJet 500"</code>.</dd></dt> - -</dl> -</blockquote> - -<p> -If Ghostscript fails to find an environment variable, it looks for a -registry value of the same name under the key</p> - -<blockquote><code> -HKEY_CURRENT_USER\Software\GPL Ghostscript\#.## -</code></blockquote> - -<p> - or if that fails, under the key</p> - -<blockquote><code> -HKEY_LOCAL_MACHINE\SOFTWARE\GPL Ghostscript\#.## -</code></blockquote> - -<p> -where #.## is the Ghostscript version number.</p> - -<p> -Ghostscript will attempt to load the Ghostscript dynamic link library <code>GSDLL32.DLL</code> in the following order:</p> -<ul> -<li> In the same directory as the Ghostscript executable.</li> -<li> If the environment variable <code>GS_DLL</code> is defined, -Ghostscript tries to load the Ghostscript dynamic link library (DLL) -with the name given.</li> -<li> Using the standard Windows library search method: the directory -from which the application loaded, the current directory, the Windows -system directory, the Windows directory and the directories listed in -the PATH environment variable.</li> -</ul> - -<p> -The Ghostscript installer will create registry values -for the environment variables <code>GS_LIB</code> - and <code>GS_DLL</code>.</p> - -<h3><a name="Uninstall_Windows"></a>Uninstalling Ghostscript on Windows</h3> - -<p> -To uninstall Ghostscript, use the Control Panel, Add/Remove Programs and -remove "Ghostscript #.##" and "Ghostscript Fonts". (The entries may be -called "GPL Ghostscript" or "AFPL Ghostscript", rather than just -"Ghostscript", depending on what version of Ghostscript was installed). -Alternatively, an uninstall shortcut is also available in the Start Menu -group.</p> -<hr> - -<h2><a name="Install_VMS"></a>Installing Ghostscript on OpenVMS</h2> - -<p> -Support for OpenVMS has stagnated (and almost certainly bit-rotted), and -as the core development team has no access to an OpenVMS environment, we -are unable to bring it up to date. We will consider patches from contributors -if any wish to take on the task of getting it working again. Given the -very limited appeal of OpenVMS these days, however, we are unlikely to consider -patches with invasive code changes.</p> - -<p> -You need the file <code>GS.EXE</code> to run Ghostscript on OpenVMS, and -installing Ghostscript on an OpenVMS system requires building it first: -please read <a href="Make.htm#VMS_build">how to build Ghostscript on VMS</a> -in the documentation on building Ghostscript.</p> - -<p> -The following installation steps assume that the Ghostscript directory is -<code>DISK1:[DIR.GHOSTSCRIPT]</code>. Yours will almost certainly be in -a different location so adjust the following commands accordingly.</p> - -<ul> - -<li>Download the fonts and unpack them into -<code>DISK1:[DIR.GHOSTSCRIPT.LIB]</code>.</li> - -<li>Enable access to the program and support files for all users with: - -<blockquote><pre> -$ set file/prot=w:re DISK1:[DIR]GHOSTSCRIPT.dir -$ set file/prot=w:re DISK1:[DIR.GHOSTSCRIPT...]*.* -</pre></blockquote> -</li> -<li>Optionally, add the Ghostscript help instructions to your system wide -help file: - -<blockquote><pre> -$ lib/help sys$help:HELPLIB.HLB DISK1:[DIR.GHOSTSCRIPT.DOC]GS-VMS.HLP -</pre></blockquote> -</li> - -<li>Lastly, add the following lines to the appropriate system wide or user -specific login script. - -<blockquote><pre> -$ define gs_exe DISK1:[DIR.GHOSTSCRIPT.BIN] -$ define gs_lib DISK1:[DIR.GHOSTSCRIPT.EXE] -$ gs :== $gs_exe:gs.exe -</pre></blockquote> -</li> - -</ul> - -<p> -If you have DECWindows/Motif installed, you may wish to replace the -<code>FONTMAP.GS</code> file with <code>FONTMAP.VMS</code>. Read the -comment at the beginning of the latter file for more information.</p> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Internal.htm b/doc/Internal.htm deleted file mode 100644 index 29aea7bf..00000000 --- a/doc/Internal.htm +++ /dev/null @@ -1,95 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript Internal Operators</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Ghostscript Internal Operators</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Internal Operators">Internal Operators</a></li> -</ul> - - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Internal Operators"></a>Internal Operators</h2> - -<p> - The following operators are defined for internal use by developers. - In general these will be undefined after initialization is complete. -</p> - -<dl> -<dt><code><name> <array> .makeoperator <operator></code></dt> -<dd>Constructs and returns a new operator that is actually the given -procedure in disguise. The name is only used for printing. The operator -has the executable attribute. - -<p> -Operators defined in this way do one other thing besides running the -procedure: if an error occurs during the execution of the procedure, and -there has been no net reduction in operand or dictionary stack depth, the -operand or dictionary stack pointer respectively is reset to its position -at the beginning of the procedure.</p> - -</dd> - -</dl> - - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Language.htm b/doc/Language.htm deleted file mode 100644 index 5f7f1077..00000000 --- a/doc/Language.htm +++ /dev/null @@ -1,2293 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript and the PostScript Language</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Ghostscript and the PostScript Language</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - - <li><a href="#Capabilities">Ghostscript's capabilities in relation to PostScript</a></li> - <li><a href="#Implementation_limits">Implementation limits</a></li> - <li> - <ul> - <li><a href="#Architectural_limits">Architectural limits</a></li> - <li><a href="#Typical_memory_limits">Typical memory limits in LanguageLevel 1</a></li> - <li><a href="#VM_consumption">Other differences in VM consumption</a></li> - </ul> - </li> - <li><a href="#Additional_operators">Additional operators in Ghostscript</a></li> - <li> - <ul> - <li><a href="#Graphics_and_text">Graphics and text operators</a></li> - <li> - <ul> - <li><a href="#Transparency">Transparency</a></li> - <li> - <ul> - <li><a href="#Transparency_graphics_state_operators">Graphics state operators</a></li> - <li><a href="#Transparency_rendering_stack_operators">Rendering stack operators</a></li> - <li><a href="#Transparency_ImageType">New ImageType</a></li> - </ul> - </li> - <li><a href="#Graphics_state">Other graphics state operators</a></li> - <li><a href="#Character">Character operators</a></li> - </ul> - </li> - - <li><a href="#Other">Other operators</a></li> - <li> - <ul> - <li><a href="#Mathematical">Mathematical operators</a></li> - <li><a href="#Dictionary">Dictionary operators</a></li> - <li><a href="#Relational">Relational operators</a></li> - <li><a href="#File">File operators</a></li> - <li><a href="#Miscellaneous">Miscellaneous operators</a></li> - <li><a href="#Device">Device operators</a></li> - </ul> - </li> - </ul> - </li> - <li><a href="#Filters">Filters</a></li> - <li> - <ul> - <li><a href="#Standard_filters">Standard filters</a></li> - <li><a href="#Non_standard_filters">Non-standard filters</a></li> - <li><a href="#Unstable_filters">Unstable filters</a></li> - </ul> - </li> - <li><a href="#Device_parameters">Device parameters</a></li> - <li><a href="#Banding_parameters">Banding parameters</a></li> - <li><a href="#User_parameters">User parameters</a></li> - <li><a href="#Miscellaneous_additions">Miscellaneous additions</a></li> - <li> - <ul> - <li><a href="#Extended_semantics_of_run">Extended semantics of 'run'</a></li> - <li><a href="#DecodingResources">Decoding resources</a></li> - <li><a href="#CIDDecodingResources">CIDDecoding resources</a></li> - <li><a href="#GlyphNames2Unicode">GlyphNames2Unicode</a></li> - <li><a href="#MultipleResourceDirectories">Multiple Resource directories</a></li> - </ul> - </li> - <li><a href="#PDF_scripting">Scripting the PDF interpreter</a></li> - <li> - <ul> - <li><a href="#PS_functions">PostScript functions</a></li> - <li><a href="#PDF_PS_operators">PostScript operators</a></li> - </ul> - </li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Capabilities"></a>Ghostscript's capabilities in relation to PostScript</h2> - -<p> -The Ghostscript interpreter, except as noted below, is intended to execute -properly any source program written in the (LanguageLevel 3) -<b>PostScript</b> language as defined in the <cite>PostScript -Language Reference, Third Edition</cite> (ISBN 0-201-37922-8) published by -Addison-Wesley in mid-1999. However, the interpreter is configurable in -ways that can restrict it to various subsets of this language. -Specifically, the base interpreter accepts the Level 1 subset of the -PostScript language, as defined in the first edition of the <cite>PostScript -Language Reference Manual</cite> (ISBN 0-201-10174-2) Addison-Wesley 1985, -plus the file system, version 25.0 language, and miscellaneous additions -listed in sections A.1.6, A.1.7, and A.1.8 of the Second Edition -respectively, including allowing a string operand for the -"<code>status</code>" operator. The base interpreter may be configured -(see the <a href="Make.htm">documentation on building Ghostscript</a> for -how to configure it) by adding any combination of the following:</p> - -<ul> -<li>The ability to process PostScript Type 1 fonts. This facility is -normally included in the interpreter.</li> - -<li>The CMYK color extensions listed in section A.1.4 of the Second Edition -(including <code>colorimage</code>). These facilities are available -only if the <code>color</code>, <code>dps</code>, or -<code>level2</code> feature was selected when Ghostscript was built.</li> - -<li>The Display PostScript extensions listed in section A.1.3 of the Second -Edition, but excluding the operators listed in section A.1.2. These -facilities are available only if the <code>dps</code> feature or the -<code>level2</code> feature was selected when Ghostscript was built.</li> - -<li>The composite font extensions listed in section A.1.5 of the Second -Edition, and the ability to handle Type 0 fonts. These facilities are -available only if the <code>compfont</code> feature or the -<code>level2</code> feature was selected when Ghostscript was built.</li> - -<li>The ability to load TrueType fonts and to handle PostScript Type 42 -(encapsulated TrueType) fonts. These facilities are available only if the -<code>ttfont</code> feature was selected when Ghostscript was built.</li> - -<li>The PostScript Level 2 "filter" facilities except the -<code>DCTEncode</code> and <code>DCTDecode</code> filters. These -facilities are available only if the <code>filter</code>, -<code>dps</code>, or <code>level2</code> feature was selected when -Ghostscript was built.</li> - -<li>The PostScript Level 2 <code>DCTEncode</code> and -<code>DCTDecode</code> filters. These facilities are available only if -the <code>dct</code> or <code>level2</code> feature was selected when -Ghostscript was built.</li> - -<li>All the other PostScript Level 2 operators and facilities listed in -section A.1.1 of the Second Edition and not listed in any of the other -A.1.n sections. These facilities are available only if the -<code>level2</code> feature was selected when Ghostscript was built.</li> - -<li>All PostScript LanguageLevel 3 operators and facilities listed in the -Third Edition, except as noted below. These facilities are available only -if the <code>psl3</code> feature was selected when Ghostscript was built.</li> - -<li>The ability to recognize DOS EPSF files and process only the PostScript -part, ignoring bitmap previews or other information. This facility is -available only if the <code>epsf</code> feature was selected when -Ghostscript was built.</li> -</ul> - -<p> -Ghostscript currently does not implement the following PostScript -LanguageLevel 3 facilities:</p> - -<ul> -<li>Settable <code>ProcessColorModel</code> for page devices, except for -a very few special devices.</li> - -<li><code>IODevice</code>s other than <code>%stdin</code>, -<code>%stdout</code>, <code>%stderr</code>, <code>%lineedit</code>, -<code>%statementedit</code>, <code>%os%</code>, and (if configured) -<code>%pipe%</code> and <code>%disk0%</code> through <code>%disk0%</code>.</li> -</ul> - -<p> -Ghostscript can also interpret files in the Portable Document Format (PDF) -1.7 format defined in the -<a href="http://www.adobe.com/devnet/pdf/pdf_reference.html"><em>PDF -Reference</em> Version 1.7</a>, -distributed by <a href="http://www.adobe.com/">Adobe Systems -Incorporated</a>, except as noted below. This facility can be -disabled by deselecting the <code>pdf</code> feature -when Ghostscript is built.</p> - -<p> -Ghostscript currently implements the majority of non-interactive -features defined in the PDF reference.</p> - -<p> -Ghostscript also includes a number of -<a href="#Additional_operators">additional operators</a> defined below that -are not in the PostScript language defined by Adobe.</p> - -<hr> - -<h2><a name="Implementation_limits"></a>Implementation limits</h2> - -<p> -The implementation limits show here correspond to those in Tables B.1 and -B.2 of the Second and Third Editions, which describe the quantities fully. -Where Ghostscript's limits are different from those of Adobe's -implementations (as shown in the Third Edition), Adobe's limits are also -shown.</p> - -<h3><a name="Architectural_limits"></a>Architectural limits</h3> - -<blockquote><table> -<tr><th colspan="4">Architectural limits (corresponds to Adobe table B.1)</th></tr> -<tr valign="bottom"> - <th align="left">Quantity</th> - - <th align="left">Limit</th> - - <th align="left">Type</th> - - <th align="left">Adobe</th></tr> -<tr valign="top"> <td>integer</td> - - <td>32-bit</td> - - <td>twos complement integer</td> - - <td> </td></tr> -<tr valign="top"> <td>real</td> - - <td>single-precision</td> - - <td>IEEE float</td> - - <td> </td></tr> -<tr valign="top"> <td>array</td> - - <td>16777216</td> - - <td>elements</td> - - <td>65535</td></tr> -<tr valign="top"> <td>dictionary</td> - - <td>16777215</td> - - <td>elements</td> - - <td>65535</td></tr> -<tr valign="top"> <td>string</td> - - <td>16777216</td> - - <td>characters</td> - - <td>65535</td></tr> -<tr valign="top"> <td>name</td> - - <td>16383</td> - - <td>characters</td> - - <td>127</td></tr> -<tr valign="top"> <td>filename</td> - - <td>128*</td> - - <td>characters</td> - - <td> </td></tr> -<tr valign="top"> <td><code>save</code> level</td> - - <td>none</td> - - <td>(capacity of memory)</td> - - <td>15</td></tr> -<tr valign="top"> <td><code>gsave</code> level</td> - - <td>none</td> - - <td>(capacity of memory)</td> - - <td>13</td></tr> -</table></blockquote> - -<p> -* The limit on the length of a file name is 128 characters if the name -starts with a %...% IODevice designation, or 124 characters if it does not.</p> - -<h3><a name="Typical_memory_limits"></a>Typical memory limits in LanguageLevel 1</h3> - -<blockquote><table> - -<tr><th colspan="4">Memory limits (corresponds to Adobe table B.2)</th></tr> -<tr valign="bottom"> - <th align="left">Quantity</th> - - <th align="left">Limit</th> - - <th align="left">Type</th> - - <th align="left">Adobe</th></tr> -<tr valign="top"> <td><code>userdict</code></td> - - <td>200</td> - - <td> </td> - - <td> </td></tr> -<tr valign="top"> <td><code>FontDirectory</code></td> - - <td>100</td> - <td> </td> - - <td> </td> - </tr> -<tr valign="top"> <td>operand stack</td> - - <td>800</td> - - <td> </td> - - <td>500</td></tr> -<tr valign="top"> <td>dictionary stack</td> - - <td>20</td> - <td> </td> - - <td> </td> - </tr> -<tr valign="top"> <td>execution stack</td> - - <td>250</td> - - <td> </td><td> </td></tr> -<tr valign="top"> <td>interpreter level</td> - - <td>none</td> - - <td>(capacity of memory)</td> - - <td>10</td></tr> -<tr valign="top"> <td>path</td> - - <td>none</td> - - <td>(capacity of memory)</td> - - <td>1500</td></tr> -<tr valign="top"> <td>dash</td> - - <td>11</td> - <td> </td> - - - <td> </td></tr> -<tr valign="top"> <td>VM</td> - - <td>none</td> - - <td>(capacity of memory)</td> - - <td>240000</td></tr> -<tr valign="top"> <td>file</td> - - <td>none</td> - - <td>(determined by operating system)</td> - - <td>6</td></tr> -<tr valign="top"> <td>image</td> - - <td>65535</td> - - <td>values (samples × components)<br>for 1-, 2-, 4-, or 8-bit samples</td> - - <td>3300</td></tr> -<tr valign="top"> <td> </td> - - <td>32767</td> - - <td>values for 12-bit samples</td> - - <td>3300</td></tr> -</table></blockquote> - -<h3><a name="VM_consumption"></a>Other differences in VM consumption</h3> - -<p> -In 32-bit builds packed array elements occupy either 2 bytes or 12 bytes. -The average element size is probably about 7 bytes. Names occupy 16 bytes plus the -space for the string.</p> -<p> -In 64-bit builds packed array elements occupy either 2 bytes or 16 bytes. -The average element size is probably about 9 bytes. -Names occupy 24 bytes plus the space for the string.</p> -<p> -The garbage collector doesn't reclaim portions of arrays obtained with -<tt>getinterval</tt>, rather it collects entire arrays.</p> -<hr> - -<h2><a name="Additional_operators"></a>Additional operators in Ghostscript</h2> - -<h3><a name="Graphics_and_text"></a>Graphics and text operators</h3> - -<h4><u><a name="Transparency"></a>Transparency</u></h4> -<p><b><u>NOTE:</u></b> The following paragraphs describe non-standard operators -for accessing the PDF 1.4 and later transparent imaging model through Postscript. -If used incorrectly, they can have unexpected side effects and result in undefined -behavior. As a result, these operators are disabled when <a href="Use.htm#Safer"><b>SAFER</b></a> -is in force (as it is by default from version 9.50 onwards). To utilise these operators -you will either have to disable <code>SAFER</code> (<code>-dNOSAFER</code>) or use -the command line parameter <code>-dALLOWPSTRANSPARENCY</code>. The latter will make -the custom operators available, but leave the file access controls active. -<p> -Ghostscript provides a set of operators for implementing the transparency -and compositing facilities of PDF 1.4. These are defined only if the -<code>transpar</code> option was selected when Ghostscript was built. We -do not attempt to explain the underlying graphics model here: for details, -see <a -href="http://partners.adobe.com/asn/developer/technotes.html#acrobat-pdf" -class="offsite">Adobe -Technical Note</a> #5407, "<a -href="http://partners.adobe.com/asn/developer/acrosdk/DOCS/PDF_Transparency.pdf" -class="offsite">Transparency -in PDF</a>". Previously (in 9.52 and earlier), Ghostscript's model -maintained separate alpha and mask values for opacity and shape. This -model has been changed (as of 9.53) and instead Ghostscript maintains separate -float values for stroke and fill alpha values with a boolean that indicates -if these should be interpreted as shape or alpha values to be more in line with the -PDF specification. -</p> -<p> -What follows is a subset of all the custom operators related to transparency, but -covers the most useful, most common requirements. -</p> - -<h5><a name="Transparency_graphics_state_operators"></a>Graphics state -operators</h5> - -<p>Pushing the compositor device must be done before any other marking -operations are made on the current page, and must be done per page. -Popping the compositor should be done after the last marking operation -of the page, and before the call to <code>showpage</code>. Any marking -operations made after the compositor is popped will bypass the transparent -imaging model, and may produce unexpected output. - -<dl> -<dt><code><depth> .pushpdf14devicefilter -</code></dt> -<dd>Installs the transparency compositor device into the graphics state. At -present the <code>depth</code> parameter should always be zero (<b>Subject -To Change.</b>) -</dl> -<dl> -<dt><code>- .popdf14devicefilter -</code></dt> -<dd>Removes (or, more accuracately, disables) the transparency compositor in -graphics state. -</dl> - - -<dl> -<dt><code><modename> .setblendmode -</code></dt> -<dd>Sets the blending mode in the graphics state. If the mode name is not -recognized, causes a <code>rangecheck</code> error. The initial value of -the blending mode is <code>/Compatible</code>.</dd> -</dl> - -<dl> -<dt><code>- .currentblendmode <modename></code></dt> -<dd>Returns the graphics state blend mode on the stack. -</dl> - -<dl> -<dt><code>[Deprecated as of 9.53] <0..1> .setopacityalpha -</code></dt> -<dd>Sets the opacity alpha value in the graphics state. -The initial opacity alpha value is 1. Note, it is strongly -suggested that this method not be used as it currently may -give inconsistent results when mixed with methods that -set stroke and fill alpha values. </dd> -</dl> - -<dl> -<dt><code>[Deprecated as of 9.53] - .currentopacityalpha <0..1></code></dt> -<dd>Returns the graphics state opacity alpha on the stack. Note, it is strongly -suggested that this method not be used as it currently may -give inconsistent results when mixed with methods that -set stroke and fill alpha values.</dd> -</dl> - -<dl> -<dt><code>[Deprecated as of 9.53] <0..1> .setshapealpha -</code></dt> -<dd>Sets the shape alpha value in the graphics state. -The initial shape alpha value is 1. Note, it is strongly -suggested that this method not be used as it currently may -give inconsistent results when mixed with methods that -set stroke and fill alpha values.</dd> -</dl> - -<dl> -<dt><code>[Deprecated as of 9.53] - .currentshapealpha <0..1></code></dt> -<dd>Returns the graphics state shape alpha on the stack. Note, it is strongly -suggested that this method not be used as it currently may -give inconsistent results when mixed with methods that -set stroke and fill alpha values.</dd> -</dl> - -<dl> -<dt><code><0..1> .setstrokeconstantalpha -</code></dt> -<dd>Sets the stroke alpha value in the graphics state. -The initial stroke alpha value is 1.</dd> -</dl> - -<dl> -<dt><code> - .currentstrokeconstantalpha <0..1></code></dt> -<dd>Returns the graphics state stroke alpha value on the stack.</dd> -</dl> - -<dl> -<dt><code><0..1> .setfillconstantalpha -</code></dt> -<dd>Sets the fill alpha value in the graphics state. -The initial fill alpha value is 1.</dd> -</dl> - -<dl> -<dt><code> - .currentfillconstantalpha <0..1></code></dt> -<dd>Returns the graphics state fill alpha value on the stack.</dd> -</dl> - -<dl> -<dt><code><bool> .setalphaisshape -</code></dt> -<dd>If true, the values set by setstrokeconstantalpha and setfillconstantalpha are interpreted as shape values. -The initial value of the AIS flag is <code>false</code>.</dd> -</dl> - -<dl> -<dt><code> - .currentalphaisshape <0..1></code></dt> -<dd>Returns the graphics state alpha is shape (AIS) on the stack.</dd> -</dl> - -<dl> -<dt><code><bool> .settextknockout -</code></dt> -<dd>Sets the text knockout flag in the graphics state. -The initial value of the text knockout flag is <code>true</code>.</dd> -</dl> - -<dl> -<dt><code>- .currenttextknockout <bool></code></dt> -<dd>Returns the graphics state text knockout on the stack..</dd> -</dl> - -<h5><a name="Transparency_rendering_stack_operators"></a>Rendering stack -operators</h5> - -<p> -The interpreter state is extended to include a (per-context) rendering stack -for handling transparency groups and masks (generically, "layers"). Groups -accumulate a full value for each pixel (paint plus transparency); masks -accumulate only a coverage value. Layers must be properly nested, i.e., the -'end' or 'discard' operator must match the corresponding 'begin' operator.</p> - -<p> -Beginning and ending groups must nest properly with respect to -<code>save</code> and <code>restore</code>: <code>save</code> and -<code>restore</code> do not save and restore the layer stack. Currently, -layers are not required to nest with respect to <code>gsave</code> and -<code>grestore</code>, except that the device that is current in the -graphics state when ending a layer must be the same as the device that was -current when beginning the layer. THIS AREA IS SUBJECT TO CHANGE.</p> - -<dl> -<dt><code><paramdict> <llx> <lly> <urx> <ury> -.begintransparencygroup -</code></dt> -<dd>Begins a new transparency group. The <code>ll/ur</code> coordinates -are the bounding box of the group in the current user coordinate system. -<code>paramdict</code> has the following keys:</dd> - -<dt><code>/Isolated</code></dt> -<dd>(optional) Boolean; default value = <code>false</code>.</dd> -<dt><code>/Knockout</code></dt> -<dd>(optional) Boolean; default value = <code>false</code>.</dd> - -</dl> - -<dl> -<dt><code>- .endtransparencygroup -</code></dt> -<dd>Ends the current transparency group, compositing the group being ended -onto the group that now becomes current.</dd> -</dl> - -<dl> -<dt><code><cs_set?> <paramdict> <llx> <lly> <urx> <ury> -.begintransparencymaskgroup -</code></dt> -<dd>Begins a new transparency mask, which is represented as a group. -The <code>ll/ur</code> coordinates -are the bounding box of the mask in the current user coordinate system. -<code>paramdict</code> has the following keys:</dd> - -<dt><code>/Subtype</code></dt> -<dd>(required) Name, either <code>/Alpha</code> or -<code>/Luminosity</code>.</dd> -<dt><code>/Background</code></dt> -<dd>(optional) Array of number.</dd> -<dt><code>/TransferFunction</code></dt> -<dd>(optional) Function object (produced by applying -<code>.buildfunction</code> to a Function dictionary). -<p> -The <code>cs_set</code> parameter is a boolean indicating whether the color -space for the mask group is the current color space in the graphics state, or -whether mask group color space should be inherited from the previous group -in the transparency group stack. In general, for the most consistent results, -it is recommended that this be set to <code>true</code>, and the intended -color space set in the graphics state prior to the <code>.begintransparencymaskgroup</code> -call.</p> -</dd> -</dl> - -<dl> -<dt><code><mask#> .endtransparencymask -</code></dt> -<dd>Ends the current transparency mask group, compositing the mask group being ended -and setting it as the current soft mask in the graphics state. -<p> -The <code>mask#</code> parameter indicates whether the mask should be treated as -as opacity mask (<code>0</code>) or shape (<code>1</code>). -</dd> -</dl> - -<h5><a name="Transparency_ImageType"></a>New ImageType</h5> - -<p> -The transparency extension defines a new ImageType 103, similar to ImageType -3 with the following differences:</p> - -<ul> - -<li>The required <code>MaskDict</code> is replaced by two optional -dictionaries, <code>OpacityMaskDict</code> and -<code>ShapeMaskDict</code>. If present, these dictionaries must have a -<code>BitsPerComponent</code> entry, whose value may be greater than 1. -Note that in contrast to ImageType 3, where any non-zero chunky mask value -is equivalent to 1, ImageType 103 simply takes the low-order bits of chunky -mask values.</li> - -<li>A <code>Matte</code> entry may be present in one or both mask -dictionaries, indicating premultiplication of the data values. If both -<code>MaskDict</code>s have a <code>Matte</code> entry and the values -of the two <code>Matte</code> entries are different, a -<code>rangecheck</code> error occurs.</li> - -<li><code>InterleaveType</code> appears in the <code>MaskDict</code>s, -not the <code>DataDict</code>, because each mask has its own -<code>InterleaveType</code>. <code>InterleaveType</code> 2 -(interlaced scan lines) is not supported.</li> - -</ul> - -<h4><a name="Graphics_state"></a>Other graphics state operators</h4> - - <dl> -<dt><code><int> .setoverprintmode -</code></dt> -<dd>Sets the overprint mode in the graphics state. Legal values are 0 or 1. -Per the PDF 1.3 specification, if the overprint mode is 1, then when the -current color space is <code>DeviceCMYK</code>, color components whose -value is 0 do not write into the target, rather than writing a 0 value. -THIS BEHAVIOR IS NOT IMPLEMENTED YET. The initial value of the overprint -mode is 0.</dd> -</dl> - -<dl> -<dt><code>- .currentoverprintmode <int></code></dt> -<dd>Returns the current overprint mode.</dd> -</dl> - -<h4><a name="Character"></a>Character operators</h4> - -<dl> -<dt><code><font> <charcode> %Type1BuildChar -</code></dt> -<dd>This is not a new operator: rather, it is a name known specially to the -interpreter. Whenever the interpreter needs to render a character (during -a ...<code>show</code>, <code>stringwidth</code>, or -<code>charpath</code>), it looks up the name <code>BuildChar</code> -in the font dictionary to find a procedure to run. If it does not find -this name, and if the <code>FontType</code> is 1, the interpreter -instead uses the value (looked up on the dictionary stack in the usual way) -of the name <code>%Type1BuildChar</code>. - -<p> -The standard definition of <code>%Type1BuildChar</code> is in the -initialization file <code>gs_type1.ps</code>. Users should not need to -redefine <code>%Type1BuildChar</code>, except perhaps for tracing or -debugging.</p> -</dd> -</dl> - -<dl> -<dt><code><font> <charname> %Type1BuildGlyph -</code></dt> -<dd>Provides the Type 1 implementation of <code>BuildGlyph</code>.</dd> -</dl> - -<h3><a name="Other"></a>Other operators</h3> - -<h4><a name="Mathematical"></a>Mathematical operators</h4> - -<dl> -<dt><code><number> arccos <number></code></dt> -<dd>Computes the arc cosine of a number between -1 and 1.</dd> -</dl> - -<dl> -<dt><code><number> arcsin <number></code></dt> -<dd>Computes the arc sine of a number between -1 and 1.</dd> -</dl> - -<h4><a name="Dictionary"></a>Dictionary operators</h4> - -<dl> -<dt><code>mark <key1> <value1> <key2> <value2> ... .dicttomark <dict></code></dt> -<dd>Creates and returns a dictionary with the given keys and values. This -is the same as the PostScript Level 2 <code>>></code> operator, -but is available even in Level 1 configurations.</dd> -</dl> - -<dl> -<dt><code><dict> <key> .knownget <value> true</code></dt> -<dt><code><dict> <key> .knownget false</code></dt> -<dd>Combines <code>known</code> and <code>get</code> in the -obvious way.</dd> -</dl> - - -<h4><a name="Relational"></a>Relational operators</h4> - -<dl> -<dt><code><number|string> <number|string> max <number|string></code></dt> -<dd>Returns the larger of two numbers or strings.</dd> -</dl> - -<dl> -<dt><code><number|string> <number|string> min <number|string></code></dt> -<dd>Returns the smaller of two numbers or strings.</dd> -</dl> - -<h4><a name="File"></a>File operators</h4> - -<dl> -<dt><code><file> .fileposition <integer> true</code></dt> -<dd>Returns the position of <code>file</code>. Unlike the standard -<code>fileposition</code> operator, which causes an error if the file is -not positionable, <code>.fileposition</code> works on all files, -including filters: for non-positionable files, it returns the total number -of bytes read or written since the file was opened.</dd> -</dl> - -<dl> -<dt><code><string> findlibfile <foundstring> <file> true</code></dt> -<dt><code><string> findlibfile <string> false</code></dt> -<dd>Opens the file of the given name for reading, searching through -directories <a href="Use.htm#Finding_files">as described in the usage -documentation</a>. If the search fails, <code>findlibfile</code> simply -pushes false on the stack and returns, rather than causing an error.</dd> -</dl> - -<a name="Tempfile"></a> -<dl> -<dt><code><prefix_string|null> <access_string> .tempfile -<string> <file></code></dt> -<dd>Creates and opens a temporary file -like the <code>file</code> operator, also returning the file name. There -are three cases for the <code><prefix_string|null></code> operand: - -<ul> -<li><code>null</code>: create the file in the same directory and with the -same name conventions as other temporary files created by the Ghostscript -implementation on this platform. E.g., the temporary file might be named -<code>/tmp/gs_a1234</code>.</li> -<li>A string that contains only alphanumeric characters, underline, -and dash: create the file in the standard temporary directory, but use -the -<code><prefix_string></code> as the first part of the file name. -E.g., if <code><prefix_string></code> is <code>xx</code>, the -temporary file might be named <code>/tmp/xxa1234</code>.</li> -<li>A string that is the beginning of an absolute file name: use the -<code><prefix_string></code> as the first part of the file name. -E.g., if <code><prefix_string></code> is -<code>/my/tmpdir/zz</code>, the temporary file might be named -<code>/my/tmpdir/zza1234</code>. -<p> - -When running in <code>SAFER</code> mode, the absolute path must -be one of the strings on the permit file writing list -(see <a href="Use.htm#Safer"><b>-dSAFER</b></a>) .</p></li> -</ul> -</dd> -</dl> - -<p> -Ghostscript also supports the following <code>IODevice</code> in -addition to a subset of those defined in the Adobe documentation:</p> -<ul> - <li> - <code>%pipe%command</code>, which opens a pipe on the given command. - This is supported only on operating systems that provide - <code>popen</code> (primarily Unix systems, and not all of those).</li> - <li> - <code>%disk#%</code>, which emulates the %disk0 - through %disk9 devices on some Adobe PostScript printers. This pseudo - device provides a flat filenaming system with a user definable location - for the files (/Root). These devices will only be present if the - diskn.dev feature is specified during the build. - - <p>This feature is intended to allow compatibility with font downloaders - that expect to store fonts on the %disk device of the printer.</p> - <p> - Use of the %disk#% devices requires that the location of files be given - by the user setting the /Root device parameter. The syntax for setting - the /Root parameter is:<pre> - mark /Root (directory_specification) (%disk#) .putdevparams - </pre> - For example, to store the files of the %disk0 device on the directory - /tmp/disk0, use:<pre> - mark /Root (/tmp/disk0/) (%disk0) .putdevparams - </pre></p> - <p>The files will be stored in the specified directory with arbitrary names. - A mapping file is used to store the association between the file - names given for the file operations on the %diskn# device and the file - that resides in the /Root directory.</p> - </li> -</ul> - -<h4><a name="Miscellaneous"></a>Miscellaneous operators</h4> - -<dl> -<dt><code><array> bind <array></code></dt> -<dd>Depending on the command line parameters <code>bind</code> is redefined as:</dd> -</dl> - -<blockquote><table> -<tr valign="bottom"> - <th valign="bottom" align="left">Flag</th> - - <th valign="bottom" align="left">Definition</th></tr> -<tr valign="top"> <td>DELAYBIND</td> - - <td>returns the argument, stores the argument for later use by <code>.bindnow</code></td></tr> -</table></blockquote> - - -<dl> -<dt><code><array> .bind <array></code></dt> -<dd>Performs standard <code>bind</code> operation as defined in PLRM regardless of -the DELAYBIND flag.</dd> -</dl> - -<a name="bindnow"></a> -<dl> -<dt><code>- .bindnow -</code></dt> -<dd>Applies <code>bind</code> operator to all saved procedures after binding has been -deferred through -dDELAYBIND. Note that idiom recognition has no effect for the deferred -binding because the value returned from <code>bind</code> is discarded. -<p> -Since v. 8.12 <code>.bindnow</code> undefines itself and restores standard definition of -<code>bind</code> operator. In earlier versions after calling <code>.bindnow</code>, -the postscript <code>bind</code> operator needs to be rebound to the internal implementation -<code>.bind</code>, as in this fragment from the ps2ascii script: -<blockquote><pre><tt>DELAYBIND { - .bindnow - /bind /.bind load def -} if -</tt></pre></blockquote> -This is necessary for correct behavior with later code that uses the <code>bind</code> operator.</p> -</dd> -</dl> - -<dl> -<dt><code><string> getenv <string> true</code></dt> -<dt><code><string> getenv false</code></dt> -<dd>Looks up a name in the shell environment. If the name is found, -returns the corresponding value and true; if the name is not found, returns -false.</dd> -</dl> - -<dl> -<dt><code><string> <boolean> .setdebug -</code></dt> -<dd>Sets or clears any subset of the debugging flags included in -<code><string></code> based on the value of -<code><boolean></code>. These correspond to the debug -flags set by <code>-Z</code> on the command line and enable -debug and tracing output from various internal modules. - -<p>Note that most tracing output is only produced if the Ghostscript -interpreter was built with the <code>DEBUG</code> preprocessor -symbol defined.</p> - -<p>The <code>zsetdebug()</code> C function, which implements this -operator, is a useful breakpoint for debuggers. -Inserting '<code>() true .setdebug</code>' in the interpreted code will -trigger a breakpoint at that location without side effects. The -current flag state is available in C as the <code>gs_debug[]</code> -array, indexed by character value. The <code>zsetdebug</code> function will -be entered, and <code>gs_debug[]</code> updated, whether or not Ghostscript -is built with the <code>DEBUG</code> preprocessor symbol defined, so this -is useful even with release builds.</p> -</dd> -</dl> - -<dl> -<dt><code>- .setsafe -</code></dt> -<dd>If Ghostscript is started with <code>-dNOSAFER</code> or -<code>-dDELAYSAFER</code>, this operator can be used to enter <b>SAFER</b> -mode (see <a href="Use.htm#Safer"><b>-dSAFER</b></a>) -<p> -<strong>The following is deprecated, see <a href="Use.htm#Safer"><b>-dSAFER</b></a></strong> -<p> -Since <b>SAFER</b> mode is implemented with userparameters and device parameters, -it is possible to use <code>save</code> and <code>restore</code> before -and after <code>.setsafe</code> to return to <b>NOSAFER</b> mode, but note -that such a save object is accessible to any procedures or file run in <b>SAFER</b> mode. -A malicious file with an unbalanced restore could potentially restore back to a point where -SAFER was not in operation.</p> -<p> -<b>Note: This uses setpagedevice to change .LockSafetyParams, so the page -will be erased as a side effect of this operator</b></p> -</dd> -</dl> - -<dl> -<dt><code>- .locksafe -</code></dt> -<dd> -<p> -<strong>The following is deprecated, see <a href="Use.htm#Safer"><b>-dSAFER</b></a></strong> -<p> -This operator sets the current device's <code>.LockSafetyParams</code> -and the <code>LockFilePermissions</code> userparameter true as well as -adding the paths on LIBPATH and FONTPATH and the paths given by the -system params /GenericResourceDir and /FontResourceDir to the current -PermitFileReading list of paths. -<p> -If Ghostscript is started with <code>-dNOSAFER</code> or -<code>-dDELAYSAFER</code>, this operator can be used to enter <b>SAFER</b> -mode with the current set of <code>PermitFile...</code> user parameters -in effect. Since <code>.setsafe</code> sets the <code>PermitFile...</code> -user parameters to empty arrays, a script or job server that needs to -enable certain paths for file Reading, Writing and/or Control can use this -operator to perform the locking needed to enter <b>SAFER</b> mode.</p> -<p> -For example, to enable reading everywhere, but disallow writing and file -control (deleting and renaming files), the following can be used:</p> -<pre> - { << /PermitFileReading [ (*) ] - /PermitFileWriting [ ] - /PermitFileControl [ ] - >> setuserparams - .locksafe - } stopped pop -</pre> -<p>In the above example, use of stopped will allow the use of this sequence on -older versions of Ghostscript where <code>.locksafe</code> was not an operator.</p> -<p> -<b>Note: This uses setpagedevice to change .LockSafetyParams, so the page -will be erased as a side effect of this operator</b></p> -<p> -See also <a href="#LockSafetyParams">.LockSafetyParams</a> and -<a href="#User_parameters">User Parameters</a>.</p> -</dd> -</dl> - -<dl> -<dt><a name=".addcontrolpath"></a> -<code><name> <string> .addcontrolpath</code></dt> -<dd> -Adds a single path to the file access control lists. -<p>The <name> parameter can be one of: -<ul> -<li> -<p><code>/PermitFileReading</code> -</li> -<li> -<p><code>/PermitFileWriting</code> -</li> -<li> -<p><code>/PermitFileControl</code> -</li> -</ul> -<p>Whilst the string parameter is the path to be added to the requested list. -<p><strong>NOTE: Any attempt to call this operator after <a href="#activatepathcontrol">.activatepathcontrol</a> -has been called will result in a <code>Fatal</code> error, and the interpreter -will immediately exit.</strong> -</dd> -</dl> - -<dl> -<dt><a name=".activatepathcontrol"></a> -<code>.activatepathcontrol</code></dt> -<dd> -Activates file access controls. Once activated, these access controls remain -in place until the interpreter shuts down. -</dd> -</dl> - -<dl> -<dt><a name=".currentpathcontrolstate"></a> -<code>.currentpathcontrolstate</code></dt> -<dd> -Returns <code>true</code> on the operand stack if file access control has been -activated, <code>false</code> if not. -</dd> -</dl> - -<dl> -<dt><a name=".genordered"></a> -<code><dict> .genordered <dict></code> (default: /OutputType /Type3).</dt> -<dt><code><dict> .genordered <string></code> (/OutputType /ThreshString).</dt> -<dt><code><dict> .genordered <array></code> (/OutputType /TOSArray).</dt> -<dd>This operator creates an ordered dither screening pattern with the parameters from the dictionary, returning (by default) a PostScript HalftoneType 3 (threshold array based) dictionary suitable for use with <code>sethalftone</code> or as a component Halftone of a <code>HalftoneType 5</code> Halftone dictionary. The /OutputType parameter can also select other than Halftone Type 3 as the return paramter, -<code><dict></code> has the following keys (all are optional):</dd> -<dt><code>/Frequency</code></dt> -<dd>Integer; default value = 75</dd> -<dt><code>/Angle</code></dt> -<dd>Integer; default value = 0</dd> -<dt><code>/HResolution</code></dt> -<dd>Real or Integer; default value is device X resolution.</dd> -<dt><code>/VResolution</code></dt> -<dd>Real or Integer; default value is device Y resolution.</dd> -<dt><code>/DotShape</code></dt> -<dd>Integer; default value = 0 (CIRCLE). Other shapes available are:</dd> -<dd> 1=REDBOOK, 2=INVERTED, 3=RHOMBOID, 4=LINE_X, 5=LINE_Y, 6=DIAMOND1, 7=DIAMOND2, 8=ROUNDSPOT,</dd> -<dt><code>/SuperCellSize</code></dt> -<dd>Integer; default value = 1 -- actual cell size determined by Frequency, Angle, H/V Resolution.</dd> -<dd>A larger value will allow more levels to be attained.</dd> -<dt><code>/Levels</code></dt> -<dd>Integer; default value = 1 -- actual number of gray levels is determined by Frequency and H/V Resolution.</dd> -<dd>SuperCellSize may need to be specified large enough to achieve the requested number of gray levels.</dd> -<dt><code>/OutputType</code></dt> -<dd>Name; default value = /Type3 (HalftoneType 3 dictionary). Other shapes available are:</dd> -<dt><code>/ThreshString</code></dt> -<dd> -First two bytes are width (high byte first), next two bytes are height, followed by the -threshold array bytes (same as /Thresholds of the Type3 dictionary). -</dd> -<dt><code>/TOSArray</code></dt> -<dd> -First element is the width, next is the height, followed by pairs X, then Y, of the turn-on-sequence of the threshold array. This information can be used to construct a threshold array with a transfer function "pickled into" the threshold array, which is useful if the turn-on-sequence has more than 256 pairs. Refer to toolbin/halftone/thresh_remap for more information.</dt> -</dd> -</dl> - -<dl> -<dt><a name=".shellarguments"></a> -<code>.shellarguments</code></dt> -<dd> -<p>This operator is used to access the ARGUMENTS command line option. -<p>Relies on Ghostscript being called with the "--" command -line option - see <a href="Use.htm#Input_control">Input Control</a> -<p>See examples in lib for more information. -</dd> -</dl> - - -<h4><a name="Device"></a>Device operators</h4> - -<dl> -<dt><code><device> copydevice <device></code></dt> -<dd>Copies a device. The copy is writable and installable. The copy is -created in the current VM (local or global), usually local VM for executing -ordinary PostScript files.</dd> -</dl> - -<dl> -<dt><code><devicename> finddevice <device></code></dt> -<dd>Creates a default instance of a device specified by name. The instance -is created in global VM. If <code>finddevice</code> is called more than -once with the same device name, it creates the default instance the first -time, and returns the same instance thereafter.</dd> -</dl> - -<dl> -<dt><code><devicename> findprotodevice <device></code></dt> -<dd>Finds the prototype of a device specified by name. A prototype can be -used with <code>getdeviceprops</code> or other parameter-reading -operators, but it is read-only and cannot be set with -<code>setdevice</code>: it must be copied first.</dd> -</dl> - -<dl> -<dt><code><matrix> <width> <height> <palette> makeimagedevice <device></code></dt> -<dd>Makes a new device that accumulates an image in memory. <code> -matrix</code> is the initial transformation matrix: it must be orthogonal -(that is, [a 0 0 b x y] or -[0 a b 0 x y]). <code>palette</code> is a -string of 2^<small><sup><b>N</b></sup></small> or -3 × 2^<small><sup><b>N</b></sup></small> elements, -specifying how the 2^<small><sup><b>N</b></sup></small> possible pixel -values will be interpreted. Each element is interpreted as a gray value, -or as RGB values, multiplied by 255. For example, if you want a monochrome -image for which 0=white and 1=black, the palette should be -<code><ff 00></code>; if you want a 3-bit deep image with -just the primary colors and their complements (ignoring the fact that 3-bit -images are not supported), the palette might be <code><000000 0000ff -00ff00 00ffff ff0000 ff00ff ffff00 ffffff></code>. At present, the -palette must contain exactly 2, 4, 16, or 256 entries, and must contain an -entry for black and an entry for white; if it contains any entries that -aren't black, white, or gray, it must contain at least the six primary -colors (red, green, blue, and their complements cyan, magenta, and yellow); -aside from this, its contents are arbitrary. - -<p> -Alternatively, palette can be 16, 24, 32, or null (equivalent to 24). -These are interpreted as:</p> - -<blockquote><table> -<tr valign="bottom"> - <th valign="bottom" align="left">Palette</th> - - <th valign="bottom" align="left">Bits allocated per color</th></tr> -<tr valign="top"> <td>16</td> - - <td>5 red, 6 green, 5 blue</td></tr> -<tr valign="top"> <td>24</td> - - <td>8 red, 8 green, 8 blue</td></tr> -<tr valign="top"> <td>32</td> - - <td>8C, 8M, 8Y, 8K</td></tr> -</table></blockquote> - -<p> -Note that one can also make an image device (with the same palette as an -existing image device) by copying a device using the -<code>copydevice</code> operator.</p> -</dd> -</dl> - -<dl> -<dt><code><device> <index> <string> copyscanlines <substring></code></dt> -<dd>Copies one or more scan lines from an image device into a string, -starting at a given scan line in the image. The data is in the same format -as for the <code>image</code> operator. It is an error if the device is -not an image device or if the string is too small to hold at least one -complete scan line. Always copies an integral number of scan lines.</dd> -</dl> - -<dl> -<dt><code><device> setdevice -</code></dt> -<dd> -<p> -Sets the current device to the specified device. Also resets the -transformation and clipping path to the initial values for the device. -Signals an <code>invalidaccess</code> error if the device is a -prototype or if <a href="Language.htm#LockSafetyParams">.LockSafetyParams</a> -is true for the current device.</p> -<p> -Some device properties may need to be set with <tt>putdeviceprops</tt> before -<code>setdevice</code> is called. For example, the pdfwrite device will try -to open its output file, causing an <tt>undefinedfilename</tt> error if -<code>OutputFile</code> hasn't been set to a valid filename. Another -method in such cases is to use the level 2 operator instead: - - <code><< /OutputDevice /pdfwrite /OutputFile -(MyPDF.pdf) >> setpagedevice</code>.</p></dd> - -</dl> - -<dl> -<dt><code>- currentdevice <device></code></dt> -<dd>Gets the current device from the graphics state.</dd> -</dl> - -<dl> -<dt><code><device> getdeviceprops <mark> <name1> <value1> ... <namen> <valuen></code></dt> -<dd>Gets the properties of a device. See the section on -<a href="#Device_parameters">device parameters</a> below for details.</dd> -</dl> - -<dl> -<dt><code><mark> <name1> <value1> ... <namen> <valuen> <device> putdeviceprops <device></code></dt> -<dd>Sets properties of a device. May cause <code>undefined</code>, -<code>invalidaccess</code>, <code>typecheck</code>, <code>rangecheck</code>, or -<code>limitcheck</code> errors.</dd> -</dl> - -<hr> - -<h2><a name="Filters"></a>Filters</h2> - -<h3><a name="Standard_filters"></a>Standard filters</h3> - -<p> -In its usual configuration, Ghostscript supports all the standard PostScript -LanguageLevel 3 filters, both encoding and decoding, except that it does not -currently support:</p> - -<ul> - -<li>the <code>EarlyChange</code> key in the <code>LZWEncode</code> -filter.</li> - -</ul> - -<p> -Ghostscript also supports additional keys in the optional dictionary -operands for some filters. For the <code>LZWDecode</code> filter:</p> - -<dl> -<dt><code>InitialCodeLength <integer></code> (default 8)</dt> -<dd>An integer between 2 and 11 specifying the initial number of data bits -per code. Note that the actual initial code length is 1 greater than this, -to allow for the reset and end-of-data code values.</dd> -</dl> - -<dl> -<dt><code>FirstBitLowOrder <boolean></code> (default false)</dt> -<dd>If true, codes appear with their low-order bit first.</dd> -</dl> - -<dl> -<dt><code>BlockData <boolean></code> (default false)</dt> -<dd>If true, the data is broken into blocks in the manner specified for the -GIF file format.</dd> -</dl> - -<p> -For the <code>CCITTFaxEncode</code> and <code>CCITTFaxDecode</code> -filters:</p> - -<dl> -<dt><code>DecodedByteAlign <integer></code> (default 1)</dt> -<dd>An integer <b>N</b> with the value 1, 2, 4, 8, or 16, specifying that -decoded data scan lines are always a multiple of <b>N</b> bytes. The -encoding filter skips data in each scan line from Columns to the next -multiple of <b>N</b> bytes; the decoding filter pads each scan line to a -multiple of <b>N</b> bytes.</dd> -</dl> - -<h3><a name="Non_standard_filters"></a>Non-standard filters</h3> - -<p> -In addition to the standard PostScript LanguageLevel 3 filters, Ghostscript -supports the following non-standard filters. Many of these filters are used -internally to implement standard filters or facilities; they are almost -certain to remain, in their present form or a backward-compatible one, in -future Ghostscript releases.</p> - -<dl> -<dt><code><target> /BCPEncode filter <file></code></dt> -<dt><code><source> /BCPDecode filter <file></code></dt> -<dd>Create filters that implement the Adobe Binary Communications Protocol. -See Adobe documentation for details.</dd> -</dl> - -<dl> -<dt><code><target> <seed_integer> /eexecEncode filter <file></code></dt> -<dd>Creates a filter for encrypting data into the encrypted format described -in the Adobe Type 1 Font Format documentation. The -<code>seed_integer</code> must be 55665 for the <code>eexec</code> -section of a font, or 4330 for a <code>CharString</code>. Note that for -the <code>eexec</code> section of a font, this filter produces binary -output and does not include the initial 4 (or <code>lenIV</code>) garbage -bytes.</dd> -</dl> - -<dl> -<dt><code><source> <seed_integer> /eexecDecode filter <file></code></dt> -<dt><code><source> <dict> /eexecDecode filter <file></code></dt> -<dd>Creates a filter for decrypting data encrypted as described in the Adobe -Type 1 Font Format documentation. The <code>seed_integer</code> must be -55665 or 4330 as described just above. PDF interpreters don't skip space characters -after operator <code>eexec</code>. Use <code>keep_spaces = true</code> for -decoding embedded PDF fonts. Recognized dictionary keys are: - -<blockquote> -<code>seed <16-bit integer></code> (required)<br> -<code>lenIV <non-negative integer></code> (default=4)<br> -<code>eexec <bool></code> (default=<code>false</code>)<br> -<code>keep_spaces <bool></code> (default=<code>false</code>) -</blockquote> -</dd> -</dl> - -<dl> -<dt><code><target> /MD5Encode filter <file></code></dt> -<dd>Creates a filter that produces the 16-byte MD5 digest of the input. -Note that no output is produced until the filter is closed.</dd> -</dl> - -<dl> -<dt><code><source> <hex_boolean> /PFBDecode filter <file></code></dt> -<dd>Creates a filter that decodes data in <code>.PFB</code> format, the -usual semi-binary representation for Type 1 font files on IBM PC and -compatible systems. If <code>hex_boolean</code> is true, binary packets -are converted to hex; if false, binary packets are not converted.</dd> -</dl> - -<dl> -<dt><code><target> <dict> /PixelDifferenceEncode filter <file></code></dt> -<dt><code><source> <dict> /PixelDifferenceDecode filter <file></code></dt> -<dd>Implements the Predictor=2 pixel-differencing option of the LZW -filters. Recognized keys are: - -<blockquote> -<code>Colors <integer></code> (1 to 4, default=1)<br> -<code>BitsPerComponent <integer></code> (1, 2, 4, or 8, default=8)<br> -<code>Columns <integer></code> (>= 0, required) -</blockquote> - -<p> -See the Adobe <a href="http://partners.adobe.com/public/developer/pdf/index_reference.html"><em>PDF Reference Manual</em></a> for details.</p> -</dd> -</dl> - -<dl> -<dt><code><target> <dict> /PNGPredictorEncode filter <file></code></dt> -<dt><code><source> <dict> /PNGPredictorDecode filter <file></code></dt> -<dd><p>Implements the "filter" algorithms of the -<a href="http://www.libpng.org/pub/png/">Portable Network Graphics (PNG) -graphics format</a>. Recognized keys are:</p> - -<blockquote><table> -<tr><th colspan="3">Keys recognized in PNG filter algorithms</th></tr> -<tr valign="bottom"> - <th align="left">Key</th> - - <th align="left">Range</th> - - <th align="left">Default</th></tr> -<tr valign="top"> <td><code>Colors <integer></code></td> - - <td>1 to 16</td> - - <td>16</td></tr> -<tr valign="top"> <td><code>BitsPerComponent <integer></code></td> - - <td>1, 2, 4, 8, or 16</td> - - <td>8</td></tr> -<tr valign="top"> <td><code>Columns <integer></code></td> - - <td>>= 0</td> - - <td>1</td></tr> -<tr valign="top"> <td><code>Predictor <integer></code></td> - - <td>10 to 15</td> - - <td>15</td></tr> -</table></blockquote> - -<p> -The <code>Predictor</code> is the PNG algorithm number + 10 for the -<code>Encoding</code> filter; the <code>Decoding</code> filter -ignores <code>Predictor</code>. 15 means the encoder attempts to -optimize the choice of algorithm. For more details see the PNG -specification</p> - -<blockquote> -<a href="http://www.w3.org/TR/WD-png-960128.html">http://www.w3.org/TR/WD-png-960128.html</a> -</blockquote> -</dd> -</dl> - -<dl> -<dt><code><target> /TBCPEncode filter <file></code></dt> -<dt><code><source> /TBCPDecode filter <file></code></dt> -<dd>Create filters that implement the Adobe Tagged Binary Communications -Protocol. See Adobe documentation for details.</dd> -</dl> - -<dl> -<dt><code><target> /zlibEncode filter <file></code></dt> -<dt><code><source> /zlibDecode filter <file></code></dt> -<dd>Creates filters that use the data compression method variously known as -'zlib' (the name of a popular library that implements it), 'Deflate' (as in -<a href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951</a>, which is a -detailed specification for the method), 'gzip' (the name of a popular -compression application that uses it), or 'Flate' (Adobe's name). Note that -the PostScript <code>Flate</code> filters are actually a combination of -this filter with an optional predictor filter.</dd> -</dl> - -<h3><a name="Unstable_filters"></a>Unstable filters</h3> - -<p> -Some versions of Ghostscript may also support other non-standard filters for -experimental purposes. The current version includes the following such -filters, which are not documented further. No code should assume that these -filters will exist in compatible form, or at all, in future versions.</p> - -<dl> -<dt><code><target/source> <string> ByteTranslateEncode/Decode filter <file></code></dt> -<dd><code>string</code> must be a string of exactly 256 bytes. Creates a -filter that converts each input byte <em>b</em> to -<code>string</code>[<em>b</em>]. Note that the <code>Encode</code> -and <code>Decode</code> filters operate identically: the client must -provide a <code>string</code> for the <code>Decode</code> filter that -is the inverse mapping of the <code>string</code> for the -<code>Encode</code> filter.</dd> -</dl> - -<dl> -<dt><code><target/source> <dict> BoundedHuffmanEncode/Decode filter <file></code></dt> -<dd>These filters encode and decode data using Huffman codes. Since these -filters aren't used anywhere, we don't document them further, except to note -the recognized dictionary keys, which must be set identically for encoding -and decoding: - -<blockquote> -<code>FirstBitLowOrder <bool></code> (default=false)<br> -<code>MaxCodeLength <int></code> (default=16)<br> -<code>EndOfData <bool></code> (default=true)<br> -<code>EncodeZeroRuns <int></code> (default=256)<br> -<code>Tables <int_array></code> -</blockquote> -</dd> -</dl> - -<dl> -<dt><code><target/source> <dict> BWBlockSortEncode/Decode filter <file></code></dt> -<dd>This filter implements the Burroughs-Wheeler block sorting compression -method, which we've heard is also used in the popular <code>bzip2</code> -compression application. See <a -href="http://sources.redhat.com/bzip2/">http://sources.redhat.com/bzip2/</a> -for more information. The only recognized dictionary key is: - -<blockquote> -<code>BlockSize <integer></code> (default=16384) -</blockquote> -</dd> -</dl> - -<hr> - -<h2><a name="Device_parameters"></a>Device parameters</h2> - -Ghostscript supports the concept of device parameters for all devices, not -just page devices. (For non-page devices, these are accessible through -<code>getdeviceprops</code> and <code>putdeviceprops</code>, as -indicated above.) Here are the currently defined parameters for all -devices: - -<dl> -<dt><a name="LockSafetyParams"></a> -<code>.LockSafetyParams <boolean></code></dt> -<dd>This parameter allows for improved system security by preventing -PostScript programs from being able to change potentially dangerous -device paramters such as OutputFile. This parameter cannot be set false -if it is already true. -<p> -If this parameter is true for the current device, attempt to set a new -device that has <code>.LockSafetyParams</code> false will signal an -<code> invalidaccess</code> error.</p> -</dd> -</dl> - -<dl> -<dt><code>BitsPerPixel <integer> (usually read-only)</code></dt> -<dd>Number of bits per pixel.</dd> -</dl> - -<dl> -<dt><code>.HWMargins [<four floats>]</code></dt> -<dd>Size of non-imageable regions around the edges of the page, in points -(units of 1/72in; see the <a href="Devices.htm#Measurements">notes on -measurements</a> in the documentation on devices).</dd> -</dl> - -<dl> -<dt><code>HWSize [<integer> <integer>]</code></dt> -<dd>X and Y size in pixels.</dd> -</dl> - -<dl> -<dt><code>%MediaSource <integer></code></dt> -<dd>The input tray key as determined by setpagedevice. PostScript -language programs don't set this parameter directly; they can -<em>request</em> a particular tray through the MediaPosition -setpagedevice parameter, but the setpagedevice logic need not -necessarily honor the request. Devices which support switchable trays -should implement %MediaSource in their put_params device procedure, -but (unlike most other such parameters) need not implement -corresponding reading logic in get_params.</dd> -</dl> - -<dl> -<dt><code>%MediaDestination <integer></code></dt> -<dd>The output tray key as determined by setpagedevice. Handling by -devices should be parallel to %MediaSource.</dd> -</dl> - -<dl> -<dt><code>.IgnoreNumCopies <boolean></code></dt> -<dd>Some page description languages support a NumCopies parameter. -This parameter instructs the device to ignore this, producing only -one copy of the document on output. Note that some devices ignore -NumCopies regardless because of limitation of the output format -or the implementation.</dd> -</dl> - -<dl> -<dt><code>Name <string> (read-only)</code></dt> -<dd>The device name. Currently the same as <code>OutputDevice</code>.</dd> -</dl> - -<dl> -<dt><code>Colors, GrayValues, RedValues, GreenValues, BlueValues, ColorValues (usually read-only)</code></dt> -<dd>As for the <code>deviceinfo</code> operator of Display PostScript. -<code>Red</code>, <code>Green</code>, <code>Blue</code>, and -<code>ColorValues</code> are only defined if -<code>Colors</code> > 1.</dd> -</dl> - -<dl> -<dt><code>TextAlphaBits, GraphicsAlphaBits (usually read-only)</code></dt> -<dd>The number of bits of anti-aliasing information for text or graphics -respectively. Legal values are 1 (no anti-aliasing, the default for most -devices), 2, or 4. -<p>Because this feature relies upon rendering the input it is incompatible, and will generate -an error on attempted use, with any of the vector output devices.</p> -</dd> -</dl> - -<p> -Ghostscript also supports the following read-only parameter that is not a -true device parameter:</p> - -<dl> -<dt><code>.EmbedFontObjects <integer></code></dt> -<dd>If non-zero, indicates that the device may embed font objects (as -opposed to bitmaps for individual characters) in the output. The purpose of -this parameter is to disable third-party font renderers for such devices. -(This is zero for almost all devices.)</dd> -</dl> - -<p> -In addition, the following are defined per Adobe's documentation for the -<code>setpagedevice</code> operator:</p> - -<blockquote> -<code>Duplex</code> (if supported)<br> -<code>HWResolution</code><br> -<code>ImagingBBox</code><br> -<code>Margins</code><br> -<code>LeadingEdge</code><br> -<code>MediaPosition</code><br> -<code>NumCopies</code> (for printers only)<br> -<code>Orientation</code> (if supported)<br> -<code>OutputDevice</code><br> -<code>PageOffset</code> (write-only)<br> -<code>PageSize</code><br> -<code>ProcessColorModel</code> (usually read-only)<br> -</blockquote> - -<p> -Some devices may only allow certain values for <code>HWResolution</code> -and <code>PageSize</code>. The null device ignores attempts to set -<code>PageSize</code>; its size is always <code>[0 0]</code>.</p> - -<p> -It should be noted that calling <tt>setpagedevice</tt> with one of the above keys may reset the effects of any <code>pdfmark</code> commands up to that point. In particular this is true of HWResolution, a behavior that differs from Adobe Distiller.</p> - -<a name="Banding_parameters"></a> -<p><b> -For raster printers and image format (jpeg*, tiff*, png* ...) devices these -page device parameters are also defined:</b></p> -<dl> -<dt><code>MaxBitmap <integer></code></dt> -<dd>Maximum space for a full page raster image (bitmap) in memory. -<p>This value includes the space for padding raster lines and for an array of -pointers for each raster line, thus the <code>MaxBitmap</code> value to allow -a given PageSize of a specific number of bits per pixel to be rendered in a -full page buffer may be somewhat larger than the bitmap size alone.</p> -</dd> -</dl> - -<dl> -<dt><code>BandListStorage <file|memory></code></dt> -<dd>The default is determined by the make file macro <code>BAND_LIST_STORAGE</code>. -Since <code>memory</code> is always included, specifying <code>-sBandListStorage=memory</code> -when the default is <code>file</code> will use memory based storage for the -band list of the page. This is primarily intended for testing, but if the disk I/O is -slow, band list storage in memory may be faster. -</dd> -</dl> - -<dl> -<dt><code>BufferSpace <integer></code></dt> -<dd>Size of the buffer space for band lists, if the full page raster image -(bitmap) is larger than <code>MaxBitmap</code> (see above.) - -<p>The buffer space is used to collect display list (clist) commands for the -bands and then to consolidate those commands when writing the clist to the -selected BAND_LIST_STORAGE device (memory or file) set when Ghostscript is compiled.</p> -<p>If <code>MaxBitmap</code> (above) forces banding mode, and if <code>BufferSpace</code> -is large enough, the display list (clist) will consist of a single band.</p> -<p>The <code>BufferSpace</code> will determine the size of the 'consolidation' -buffer (above) even if the <code>MaxBitmap</code> value is low enough to force -banding/clist mode.</p> -</dd> -</dl> - -<dl> -<dt><code>BGPrint <boolean></code></dt> -<dd>With many printer devices, when the display list (clist) banding mode is being used, -the page rendering and output can be performed in a background thread. -The default value, <code>false</code>, causes the rendering and printing to be -done in the same thread as the parser. When <code>-dBGPrint=true</code>, the -page output will be overlapped with parsing and writing the clist for the next page. -<p>If the device does not support background printing, rendering and printing will -be performed as if <code>-dBGPrint=false</code>.</p> -<p>Note that the background printing thread will allocate a band buffer (size determined -by the <code>BufferSpace</code> or <code>BandBufferSpace</code> values) in addition to -the band buffer in the 'main' parsing thread.</p> -<p>If <code>NumRenderingThreads</code> is > 0, then the background printing thread -will use the specified number of rendering threads as children of the background printing -thread. The background printing thread will perform any processing of the raster data -delivered by the rendering threads. Note that BGPrint is disabled for vector devices such as pdfwrite -and NumRenderingThreads has no effect on these devices eitehr.</p> -</dd> -</dl> - -<dl> -<dt><code>GrayDetection <boolean></code></dt> -<dd>When <code>true</code>, and when the display list (clist) banding mode is being used, -during writing of the clist, the color processing logic collects information about the -colors used <b>before</b> the device color profile is applied. This allows special devices -that examine <code>dev->icc_struct->pageneutralcolor</code> with the information that all -colors on the page are near <i>neutral</i>, i.e. monochrome, and converting the rendered -raster to gray may be used to reduce the use of color toners/inks. -<p> -Since the determination of whether or not the page uses colors is determined before the -conversion to device colors, this information is independent of the device output profile. -The determination has a small delta (<tt>DEV_NEUTRAL</tt> and <tt>AB_NEUTRAL</tt> in -<tt>base/gscms.h</tt>) to allow colors close to neutral to be detected as neutral. -Changing this value requires rebuilding.</p> -<p> -Among the devices distributed with the source, currently only the <code>pnmcmyk</code> -device supports this parameter and will produce either a <code>P7 PAM</code> CMYK output -or a <code>P5 PGM</code> Gray output depending on the use of color on the page.</p> -<p> -Also, the 'pageneutralcolor' status can be interrogated as a device parameter of the -same name. Using PostScript there are several methods:</p> -<pre> - currentpagedevice /pageneutralcolor get - - mark currentdevice getdeviceprops .dicttomark /pageneutralcolor get - - /pageneutralcolor /GetDeviceParam .special_op { exch pop }{ //false } ifelse -</pre> -<p> -Note that the <tt>pageneutralcolor</tt> state is reset to <tt>false</tt> after the -page is output, so this parameter is only valid immediately <b>before</b> <tt>showpage</tt> -is executed, although the <tt>setpagedevice EndPage</tt> procedure can be used to check -the state just prior to the actual output of the page that resets <tt>pagenuetralcolor</tt>. -For example:</p> -<pre> - << /EndPage { - exch pop 2 ne dup { - currentpagedevice /pageneutralcolor get (pageneutralcolor: ) print = flush - } if - } - >> setpagedevice -</pre> -<b>Notes:</b> -<p> -Since <code>-dGrayDetection=true</code> requires extra checking during -writing of the clist, this option should <b>only</b> be used for devices that -support the optimization of pages to monochrome, otherwise performance may be degraded -for no benefit.</p> -<p> -Since GrayDetection=true is only effective when in clist (banding) mode, it is recommended -to also force banding. For example: <b><tt>-dGrayDetection=true -dMaxBitmap=0</tt></b></p> -</dd> -</dl> - -<dl> -<dt><code>NumRenderingThreads <integer></code></dt> -<dd>When the display list (clist) banding mode is being used, bands can be rendered -in separate threads. The default value, 0, causes the rendering of bands to be -done in the same thread as the parser and device driver. <code>NumRenderingThreads</code> -of 1 or higher results in bands rendering in the specified number of 'background' -threads. -<p>The number of threads should generally be set to the number of available -processor cores for best throughput.</p> -<p>Note that each thread will allocate a band buffer (size determined by the -<code>BufferSpace</code> or <code>BandBufferSpace</code> values) in addition to -the band buffer in the 'main' thread.</p> -<p>Additoinally note that ths parameter has no effect with devices which do not generally -render to a bitmap output, such as the vector devices (eg pdfwrite) and has no effect -when rendering, but not using a clist. See <a href="Use.htm#Improving_performance">Improving_performance</a> -</p> -</dd> -</dl> - -<dl> -<dt><code>OutputFile <string></code></dt> -<dd>An empty string means "send to printer directly", otherwise specifies -the file name for output; <code>%d</code> is replaced by the page number -for page-oriented output devices; -on Unix systems <code>%pipe%</code><em>command</em> writes to a pipe. -(<code>|</code><em>command</em> also writes to a pipe, but is now -deprecated). Also see the <code>-o</code> parameter. -<p> -Attempts to set this parameter if <code>.LockSafetyParams</code> is true -will signal an <code>invalidaccess</code> error.</p> -</dd> -</dl> - -<dl> -<dt><code>OpenOutputFile <boolean></code></dt> -<dd>If true, open the device's output file when the device is opened, -rather than waiting until the first page is ready to print.</dd> -</dl> - -<dl> -<dt><code>PageCount <integer> (read-only)</code></dt> -<dd>Counts the number of pages printed on the device.</dd> -</dl> - -<p> -The following parameters are for use only by very specialized applications -that separate band construction from band rasterization. <b>Improper use may -cause unpredictable errors.</b> In particular, if you only want to allocate -more memory for banding, to increase band size and improve performance, use -the <code>BufferSpace</code> parameter, not <code>BandBufferSpace</code>.</p> - -<dl> -<dt><code>BandHeight <integer></code></dt> -<dd>The height of bands when banding. 0 means use the largest band height -that will fit within the <code>BandBufferSpace</code> (or <code>BufferSpace</code>, -if <code>BandBufferSpace</code> is not specified). If <code>BandHeight</code> -is larger than the number of lines that will fit in the buffer, opening the device will fail. -If the value is -1, the BandHeight will automatically be set to the page height -(1 band for the entire page). This is primarily for developers debugging clist issues. -</dd> -</dl> - -<dl> -<dt><code>BandWidth <integer></code></dt> -<dd>The width of bands in the rasterizing pass, in pixels. 0 means use the -actual page width. A BandWidth value smaller than the width of the page -will be ignored, and the actual page width will be used instead.</dd> -</dl> - -<dl> -<dt><code>BandBufferSpace <integer></code></dt> -<dd>The size of the band buffer in the rasterizing pass, in bytes. 0 means -use the same buffer size as for the interpretation pass.</dd> -</dl> - -<p> -Ghostscript supports the following parameter for -<code>setpagedevice</code> and <code>currentpagedevice</code> that is -not a device parameter per se:</p> - -<dl> -<dt><code>ViewerPreProcess <procedure></code></dt> -<dd>Specifies a procedure to be applied to the page device dictionary -before any other processing is done. The procedure may not alter the -dictionary, but it may return a modified copy. This "hook" is provided for -use by viewing programs such as GSview.</dd> -</dl> - -<hr> - -<h2><a name="User_parameters"></a>User parameters</h2> - -Ghostscript supports the following non-standard user parameters: - -<dl> -<dt><code>ProcessDSCComment <procedure|null></code></dt> -<dd>If not null, this procedure is called whenever the scanner detects a DSC -comment (comment beginning with <code>%%</code> or <code>%!</code>). -There are two operands, the file and the comment (minus any terminating -EOL), which the procedure must consume.</dd> -</dl> - -<dl> -<dt><code>ProcessComment <procedure|null></code></dt> -<dd>If not null, this procedure is called whenever the scanner detects a -comment (or, if <code>ProcessDSCComment</code> is also not null, a -comment other than a DSC comment). The operands are the same as for -<code>ProcessDSCComment</code>.</dd> -</dl> - -<dl> -<dt><code>LockFilePermissions <boolean></code></dt> -<dd>If <tt>true</tt>, this parameter and the three <tt>PermitFile...</tt> -parameters cannot be changed. Attempts to change any of the values -when LockFilePermissions is <tt>true</tt> will signal <code>invalidaccess</code>. -Also, when this value is <tt>true</tt>, the <code>file</code> operator -will give <code>invalidaccess</code> when attempting to open files -(processes) using the <code>%pipe</code> device. -<p> -Also when <code>LockFilePermissions</code> is <tt>true</tt>, strings -cannot reference the parent directory (platform specific). For example -<code>(../../xyz)</code> is illegal on unix, Windows -and Macintosh, and <code>([.#.#.XYZ])</code> is illegal on VMS.</p> -<p> -This parameter is set <tt>true</tt> by the <code>.setsafe</code> and -<code>.locksafe</code> operators.</p> -</dd> -</dl> - -<dl> -<dt><code>PermitFileReading <array of strings></code></dt> -<dt><code>PermitFileWriting <array of strings></code></dt> -<dt><code>PermitFileControl <array of strings></code></dt> -<dd>These parameters specify paths where file reading, writing and the -'control' operations are permitted, respectively. File control -operations are <code>deletefile</code> and <code>renamefile</code>. -For <code>renamefile</code>, the filename for the current filename -must match one of the paths on the PermitFileControl list, and the -new filename must be on <b>both</b> the PermitFileControl and the -PermitFileWriting lists of paths. -<p> -The strings can contain wildcard characters as for the <code>filenameforall</code> -operator and unless specifying a single file, will end with a <b>*</b> -for directories (folders) to allow access to all files and sub-directories -in that directory.</p> -<p> -<b>Note:</b> The strings are used for stringmatch operations similar -to <code>filenameforall</code>, thus on MS Windows platforms, use the '/' -character to separate directories and filenames or use '\\\\' to -have the string contain '\\' which will match a single '\' in the -target filename (use of '/' is strongly recommended).</p> -<p> -The <a href="Use.htm#Safer"><b>SAFER</b></a> mode and the -<code>.setsafe</code> operator set all three lists to empty arrays, -thus the only files that can be read are the <code>%stdin</code> device and -on LIBPATH or FONTPATH or the Resource paths specified by the /FontResourceDir -or /GenericResourceDir system params. Files cannot be opened for writing -anywhere and cannot be deleted or renamed except for files created with the -<a href="#Tempfile"><b>.tempfile</b></a> operator).</p> -<p> -<b>Note: </b>Limiting file reading as above is <b>NOT</b> compatible with -SAFER mode in release versions before 7.11 and corresponds to the use of -<code>-dPARANOIDSAFER</code> in version 7.04 (up to and not including -version 7.10) and GPL versions 6.53 (up to and not including 6.60).</p> -</dd> -</dl> - -<dl> -<dt><code>AlignToPixels <integer></code></dt> -<dd>Control sub-pixel positioning of character glyphs (where -applicable). A value of 1 specifies alignment of text characters to -pixels boundaries. A value of 0 to subpixels where the division factor -is set by the device parameter <code>TextAlphaBits</code>. If the -latter is 1, the same rendering results regardless of the value of -<code>AlignToPixels</code>. The initial value defaults to 1, but this -may be overridden by the command line argument -<code>-dAlignToPixels</code>.</dd> -</dl> - - -<dl> -<dt><a name="GridFitTT"></a> -<code>GridFitTT <integer></code></dt> -<dd>Control the use of True Type grid fitting. -Ghostscript, by default, uses Freetype for rendering Truetype (and most other) glyphs -(but other scaler/renderer libraries can be used), thus has access to a complete Truetype -bytecode interpreter. -<p> -This parameter controls the hinting of Truetype glyphs.</p> -<ul> -<li> -A value of 0 disables grid fitting for all True Type fonts (not generally recommended). -</li> - -<li> -A value of 1 enables the grid fitting using the native Truetype hinting bytecode -program(s). Fonts or glyphs with faulty bytecode program(s) will be rendered unhinted. -</li> - -<li> -A value 2 is scaler/renderer dependent (generally, if no alternative hinting engine is available -this will be equivalent to 1). With the Freetype (our default) this enables Freetype's built-in -autohinter. -</li> - -<li> -With Freetype, a value of 3 is effectively equivalent to 1. -</li> -</ul> -<p> -This parameter defaults to 1, but this -may be overridden on the command line with -<code>-dGridFitTT=n</code>.</p> -</dd> -</dl> - -<hr> - -<h2><a name="Miscellaneous_additions"></a>Miscellaneous additions</h2> - -<h3><a name="Extended_semantics_of_run"></a>Extended semantics of 'run'</h3> - -<p> -The operator <code>run</code> can take either a string or a file as its argument. In -the latter case, it just runs the file, closing it at the end, and trapping -errors just as for the string case.</p> - -<h3><a name="DecodingResources"></a>Decoding resources</h3> - -<p> -<code>Decoding</code> is a Ghostscript-specific resource category. It contains -various resources for emulating PostScript fonts with other font technologies. -Instances of the <tt>Decoding</tt> category are tables which map PostScript glyph -names to character codes used with TrueType, Intellifont, Microtype and other font formats.</p> - -<p> -Currently Ghostscript is capable of PostScript font emulation in 2 ways :</p> -<ul> -<li> -1. Through <a href="./Use.htm#FAPI_run">FAPI</a> plugins, and -</li> -<li> -2. With TrueType font files, using the native font renderer, by -specifying TrueType font names or files in <a href="../Resource/Init/Fontmap.GS">Resource/Init/Fontmap.GS</a>. -</li> -</ul> -<p> -<code>Decoding</code> resources are not currently used by the native font renderer.</p> - -<p> -An instance of the <code>Decoding</code> resource category is -a dictionary. The dictionary keys are PostScript glyph names and the -values are either character codes, or arrays of character codes. -Arrays are used when a single name may be mapped to various character codes - -in this case Ghostscript tries all alternatives until a success. -The name of the resource instance should -reflect the character set for which it maps. For example, -<code>/Unicode</code> <code>/Decoding</code> resource maps to -Unicode UTF-16.</p> - -<p> -The rules for using <code>Decoding</code> resources in particular -cases are specified in the configuration file -<a href="../Resource/Init/xlatmap">Resource/Init/xlatmap</a>. See the file itself for more -information.</p> - -<p> -The file format for <code>Decoding</code> resource files is -generic PostScript. -Users may want to define custom <code>Decoding</code> resources. -The <code>ParseDecoding</code> procset defined in -<a href="../Resource/Init/gs_ciddc.ps">Resource/Init/gs_ciddc.ps</a> allows representation -of the table in a comfortable form.</p> - - -<h3><a name="CIDDecodingResources"></a>CIDDecoding resources</h3> - -<p> -<code>CIDDecoding</code> resources are similar to <code>Decoding</code> -resources, except they map Character Identifiers (CIDs) rather than glyph names. -Another difference is that the native Ghostscript font renderer uses -<code>CIDDecoding</code> resources while emulate CID fonts with TrueType or OpenType fonts.</p> - -<p> -An instance of the <code>CIDDecoding</code> resource category is -a dictionary of arrays. Keys in the dictionary are integers, -which correspond to high order byte of a CID. -Values are 256-element arrays, and their indices correspond to the low order byte of a CID. -Each elemet of an array is either null, or character code (integer), or an array -of character codes (integers). The zero code represents mapping to the default character.</p> - -<p> -The dictionary includes the additional key <code>CIDCount</code>. -Its value is the maximal CID defined, plus one.</p> - -<p> -The Ghostscript library is capable of generating some <code>CIDDecoding</code> -instances automatically, using the appropriate <code>CMap</code> (character map) -resources. This covers most of practical cases if the neccessary <code>CMap</code> -resources are provided. See the table <code>.CMapChooser</code> in -<a href="../Resource/Init/gs_ciddc.ps">Resource/Init/gs_ciddc.ps</a> -for the names of automatically gerenated resources and associated <code>CMap</code>s. -They allow to mapping CNS1, GB1, Japan1, Japan2 and Korea1 CID sets to TrueType -character sets known as Unicode (exactly UTF-16), Big5, -GB1213, ShiftJIS, Johab and Wansung.</p> - -<p> -The file format for <code>CIDDecoding</code> resource file is -generic PostScript. -Users may want to define custom resources to <code>CIDDecoding</code> -resource category.</p> - -<h3><a name="GlyphNames2Unicode"></a>GlyphNames2Unicode</h3> -<p> -<code>GlyphNames2Unicode</code> is an undocumented dictionary which Adobe -PostScript printer driver uses to communicate with Adobe Distiller. -In this dictionary the keys are glyph names, the values are Unicode UTF-16 codes for them. -The dictionaly is stored in the <code>FontInfo</code> dictionary under -the key <code>GlyphNames2Unicode</code>. Ghostscript recognises it and uses -to generate <code>ToUnicode</code> CMaps with pdfwrite.</p> - -<h3><a name="MultipleResourceDirectories"></a>Multiple Resource directories</h3> - -<p> -Since 8.10 release Ghostscript maintains multiple resource directories.</p> - -<p> -Ghostscript does not distinguish <code>lib</code> and -<code>Resource</code> directories. -There is no file name conflicts because <code>lib</code> does not -contain subdirectories, but <code>Resource</code> -always store files in subdirectories.</p> - -<p> -The search method with multiple resource directories -appears not fully conforming to PLRM. We cannot unconditionally call -<code>ResourceFileName</code> while executing <code>findresource</code> -or <code>resourcestatus</code>, <code>resourceforall</code>, because -per PLRM it always returns a single path. Therefore Ghostscript -implements an extended search method in <code>findresource</code>, -<code>resourcestatus</code> and <code>resourceforall</code>, which -first calls <code>ResourceFileName</code> and checks whether the -returned path points to an existing file. If yes, the file is used, -othervise Ghostscript searches all directories specified in -<code>LIB_PATH</code>. With a single resource directory -it appears conforming to PLRM and equivalent to Adobe implementations.</p> - -<p> -<code>ResourceFileName</code> may be used for obtaining a path -where a resource file to be installed. In this case -Ghostscript to be invoked with <code>-sGenericResourceDir=path</code>, -specifying an absolute path. The default value for -<code>GenericResourceDir</code> is a relative path. Therefore -a default invocation with a PostScript installer -will install resource files into <code>/gs/Resource</code>.</p> - -<h2><a name="PDF_scripting"></a>Scripting the PDF interpreter</h2> - -<h3><a name="PS_functions"></a>PostScript functions</h3> - -<p>We have not previously documented the internals of the Ghostscript PDF interpreter, but we have, on -occasion, provided solutions that rely upon scripting the interpreter from PostScript. This was -possible because the interpreter was written in PostScript.</p> - -<p>From release 9.55.0 Ghostscript comes supplied with two PDF interpreters, the original written in PostScript -and a brand-new interpreter written in C. While the new interpreter can be run as part of the GhostPDL family -it has also been integrated into Ghostscript, and can be run from the PostScript environment in a similar fashion -to the old interpreter. We plan to deprecate, and eventually remove, the old interpreter and carry on with the new one.</p> - -<p>Because we have supplied solutions in the past based on the old interpreter, we have had to implement -the same capabilities in the integration of the new interpreter. Since this has meant discovering which internal -portions were being used, working out how those function, and duplicating them anew, it seemed a good time to -document these officially, so that in future the functionality would be available to all.</p> - -<p>The following functions existed in the original PDF interpreter and have been replicated for the new -interpreter. It should be possible to use these for the forseeable future.</p> -<dl> -<dt><code><file> runpdf - </code></dt> -<dd> Called from the modified PostScript run operator (which copies stdin to a temp - file if required). Checks for PDF collections, processes all requested pages.</dd> - -<dt><code><file> runpdfbegin -</code></dt> -<dd> This must be called before performing any further operations. Its exact action depends on which -interpreter is being used, but it essentially sets up the environment to process the file as a PDF</dd> -<dt><code><int> pdfgetpage <pagedict> | <null></code></dt> -<dd> int is a number from 1 to N indicating the desired page number from - the PDF file. Returns the a dictionary containing various informational key/value pairs. - If this fails, returns a null object.</dd> - <dt><code> - pdfshowpage_init -</code></dt> -<dd> In the PostScript PDF interpreter this simply adds 1 to the /DSCPageCount value in a dictionary. -It has no effect in the new PDF interpreter but is maintained for backwards compatibility.</dd> - -<dt><code><pagedict> pdfshowpage_setpage <pagedict></code></dt> -<dd> Takes a dictionary as returned from pdfgetpage, extracts various - parameters from it, and sets the media size for the page, taking into - account the boxes, and requested Box, Rotate value and PDFFitPage.</dd> - <dt><code><pagedict> pdfshowpage_finish -</code></dt> -<dd> Takes a dictionary as returned from pdfgetpage, renders the page content - executes showpage to transfer the rendered content to the device.</dd> - <dt><code>- runpdfend -</code></dt> -<dd> Terminates the PDF processing, executes restore and various cleanup activities.</dd> -<dt><code><file> pdfopen <dict></code></dt> -<dd> Open a PDF file and read the header, trailer - and cross-reference.</dd> - <dt><code><dict> pdfclose -</code></dt> -<dd> Terminates processing the original PDF file object. The dictionary parameter - should be the one returned from pdfopen</dd> - <dt><code><pagedict> pdfshowpage -</code></dt> -<dd> Takes a dictionary returned from pdfgetpage and calls the pdfshowpage_init - pdfshowpage_setpage, pdfshowpage_finish trio to start the page, set up the - media and render the page.</dd> - <dt><code><int> <int> dopdfpages -</code></dt> -<dd> The integers are the first and last pages to be run from the file. Runs a loop from - the fist integer to the last. NOTE! If the current dictionary contains a PDFPageList - array then we 'get' the entry from the array corresponding to the current loop - index, and use that to determine whether we should draw the page. Otherwise we - simply draw the page. Uses pdfshowpage to actually render the page.</dd> - <dt><code>- runpdfpagerange <int> <int></code></dt> -<dd> Processes the PostScript /FirstPage, /LastPage and /PageList parameters. These are used together to build an internal array - of page numbers to run, which is used by dopdfpages to actually process the pages if PageList is present, - and a FirstPage and LastPage value. Despite the name this function does not actually 'run' any pages at all. - -<p>Normal operation simply calls runpdf with an opened-for-read PostScript file object. The table below shows the normal -calling sequence</p> - -<blockquote><table> -<tr valign="bottom"> - <th align="left">Function</th> - - <th align="left">Calls</th> - - <th align="left">Calls</th> - - <th align="left">Calls</th></tr> -<tr valign="top"> - <td>runpdf</td> - - <td>runpdfbegin</td> - - <td>pdfopen</td> - - <td> </td></tr> -<tr valign="top"> - - <td> </td> - <td>process_trailer_attrs</td> - - <td> </td> - <td> </td> -</tr> -<tr valign="top"> - - <td> </td> - <td>runpdfpagerange</td> - - - <td> </td> - <td> </td></tr> -<tr valign="top"> - - <td> </td> - <td>dopdfpages</td> - - <td>pdfgetpage</td> - <td> </td></tr> -<tr valign="top"> - <td> </td> - <td> </td> - <td>pdfshowpage</td> - - <td>pdfshowpage_init</td></tr> -<tr valign="top"> - - <td> </td> - <td> </td> - <td> </td> - <td>pdfshowpage_setpage</td></tr> -<tr valign="top"> - - <td> </td> - <td> </td> - <td> </td> - <td>pdfshowpage_finish</td></tr> -<tr valign="top"> - - <td> </td> - <td>runpdfend</td> - - <td>pdfclose</td> - <td> </td></tr> -</table></blockquote> - -<p>It is important to get the number of spots and the presence of transparency correct when -rendering. Failure to do so will lead to odd output, and potentially crahses. This can be important in situations -such as N-up ordering.</p> -<p>As an example, if we have 2 A4 pages and want to render them side-by-side on A3 media, we might set up -the media size to A3, draw the first page contents, translate the origin, draw the second page contents -and then render the final content. If the first PDF page did not contain transparency, but the second did, it -would be necessary to set /PageHasTransparency before drawing the first PDF page.</p> - -<h3><a name="PDF_PS_operators"></a>PostScript operators interfacing to the PDF interpreter</h3> -<p>The PostScript functions documented above must somehow interface with the actual PDF interpreter, and this is done -using a small number of custom PostScript operators. These operators do not exist in standard PostScript; they -are specific to the Ghostscript implementation. These operators are documented here for the benefit of any -developers wishing to use them directly.</p> -</dd> - -<dt><code>dict .PDFInit <PDFContext></code></dt> -<dd> Initialises an instance of the PDF interpreter. dict is an optional dictionary that contains any interpreter-level -switches, such as PDFDEBUG, this is used to set the initial state of the PDF interpreter. -The return value is a PDFcontext object which is an opaque object to be used with the other PDF operators.</dd> -<dt><code>filename PDFcontext .PDFFile -</code></dt> -<dd> Opens a named file and associates it with the instance of the PDF interpreter. -Filename is a string containing a fully qualified path to the PDF file to open, this file must have been made accesible -by setting --permit-file-read. -</dd><dt><code>file PDFcontext .PDFStream -</code></dt> -<dd> Takes an already open (disk-based) file and associates it with the instance of the PDF interpreter. -</dd><dt><code>PDFcontext .PDFClose -</code></dt> -<dd> If the context contains an open PDF file which was opened via the .PDFfile operator, this closes the file. -Files associated with the context by the .PDFStream operator are unaffected. Regardless of the source it then shuts down the PDF interpreter and frees the associated memory. -</dd><dt><code>PDFcontext .PDFInfo dict</code></dt> -<dd> PDFcontext is a PDFcontext object returned from a previous call to .PDFInit. -The returned dictionary contains various key/value pairs with useful file level information: -<blockquote> - <code>/NumPages</code> int<br> - <code>/Creator</code> string<br> - <code>/Producer</code> string<br> - <code>/IsEncrypted</code> boolean<br> -</blockquote> -</dd><dt><code>PDFcontext .PDFMetadata -</code></dt> -<dd> PDFcontext is a PDFcontext object returned from a previous call to .PDFInit. -For the benefit of high level devices, this is a replacement for 'process_trailer_attrs' which is a seriously misnamed function now. -This function needs to write any required output intents, load and send Outlines to the device, copy the Author, Creator, Title, Subject -and Keywords from the Info dict to the output device, copy Optional Content Properties (OCProperties) to the output device. -If an AcroForm is present send all its fields and link widget annotations to fields, and finally copy the PageLabels. If we add support for anything else, it will be here too.. -</dd><dt><code>PDFcontext int .PDFPageInfo -</code></dt> -<dd> The integer argument is the page number to retrieve information for. -Returns a dictionary with the following key/value pairs: -<blockquote> - <code>/UsesTransparency</code> true|false<br> - <code>/SpotColours</code> array of names, may be empty|<br> - <code>/MediaBox</code> [llx lly urx ury]<br> - <code>/HasAnnots</code> true|false<br> - <code>/FontsUsed</code> array of names, may be empty.<br> -</blockquote> -May also contain (if they are present in the Page dictionary) -<blockquote> - <code>/ArtBox</code> [llx lly urx ury]<br> - <code>/CropBox</code> [llx lly urx ury]<br> - <code>/BleedBox</code> [llx lly urx ury]<br> - <code>/TrimBox</code> [llx lly urx ury]<br> - <code>/UserUnit</code> int<br> -</blockquote> -</dd> -<dt><code>PDFcontext int .PDFDrawPage -</code></dt> -<dd> PDFcontext is a PDFcontext object returned from a previous call to .PDFInit. -The integer argument is the page number to be processed. -Interprets the page content stream(s) of the specified page using the current graphics state. -</dd> - -<dt><code>PDFcontext int .PDFDrawAnnots -</code></dt> -<dd> PDFcontext is a PDFcontext object returned from a previous call to .PDFInit. -The integer argument is the page number to be processed. -Renders the Annotations (if any) of the specified page using the current graphics state -For correct results, the graphics state when this operator is run should be the same as when -PDFDrawPage is executed. - - -<p>Note: The PDFcontext object created by PDFInit must (clearly) have a PDF file associated -with it before you can usefully use it. Attempting to use a PDFcontext with -any of the processing operators (eg .PDFDrawPage) before using either .PDFStream of .PDFFile -to associate a file with the context will result in an error. -</p> -</dd> -</dl> -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Lib.htm b/doc/Lib.htm deleted file mode 100644 index 340b53f1..00000000 --- a/doc/Lib.htm +++ /dev/null @@ -1,1023 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>The Ghostscript Library</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>The Ghostscript Library</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#GS_library">The Ghostscript library</a> - <li><a href="#PS_operator_API">PostScript operator API</a> - <li> - <ul> - <li><a href="#Patterns">Patterns</a> - <li><a href="#Lower_level_API">Lower-level API</a> - </ul> - </li> - <li><a href="#Visual_trace">Visual Trace instructions</a> - <li><a href="#Full_example">A full example</a> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="GS_library"></a>The Ghostscript library</h2> - -<p> -This document describes the Ghostscript library, a set of procedures -to implement the graphics and filtering capabilities that are primitive -operations in the PostScript language and in Adobe Portable Document Format -(PDF). - -<p> -Ghostscript is actually two programs: a language interpreter, and a -graphics library. The library provides, in the form of C procedures, all -the graphics functions of the language, that is, approximately those -facilities listed in section 8.1 of the <cite>PostScript -Language Reference Manual</cite>, starting with the -graphics state operators. In addition, the library provides some -lower-level graphics facilities that offer higher performance in exchange -for less generality. - -<hr> - -<h2><a name="PS_operator_API"></a>PostScript operator API</h2> - -<p> -The highest level of the library, which is the one that most clients will -use, directly implements the PostScript graphics operators with procedures -named <code>gs_XXX</code>, for instance <code>gs_moveto</code> and -<code>gs_fill</code>. Nearly all of these procedures take graphics -state objects as their first arguments, such as - -<blockquote><code> -int gs_moveto(gs_state *, double, double); -</code></blockquote> - -<p> -Nearly every procedure returns an integer code which is >= 0 for a -successful return or <0 for a failure. The failure codes correspond -directly to PostScript errors, and are defined in -<code>gserrors.h</code>. - -<p> -The library implements all the operators in the following sections of the -<cite>PostScript Language Reference Manual</cite>, with the indicated -omissions and with the APIs defined in the indicated <code>.h</code> -files. A header of the form <b><em>A.h(B.h)</em></b> indicates that -<b><em>A.h</em></b> is included in <b><em>B.h</em></b>, so -<b><em>A.h</em></b> need not be included explicitly if <b><em>B.h</em></b> -is included. Operators marked with * in the "omissions" column are not -implemented directly; the library provides lower-level procedures that can -be used to implement the operator. - -<p> -There are slight differences in the operators that return multiple values, -since C's provisions for this are awkward. Also, the control structure for -the operators involving callback procedures (<code>pathforall</code>, -<code>image</code>, <code>colorimage</code>, -<code>imagemask</code>) is partly inverted: the client calls a procedure -to set up an enumerator object, and then calls another procedure for each -iteration. The <code>...show</code> operators, -<code>charpath</code>, and <code>stringwidth</code> also use an -inverted control structure. - -<blockquote><table> -<tr> - <th align="left">Section<br>(operators)</th> - - <th align="left">Headers</th> - - <th align="left">Omissions</th> - </tr> -<tr> - <td>Graphics state – device-independent</td> - - <td><code>gscolor.h</code>(<code>gsstate.h</code>)<br><code>gscolor1.h</code><br><code>gscolor2.h</code><br><code>gscspace.h</code><br><code>gshsb.h</code><br><code>gsline.h</code>(<code>gsstate.h</code>)<br><code>gsstate.h</code></td> - - <td> </td> - </tr> -<tr> - <td>Graphics state – device-dependent</td> - - <td><code>gscolor.h</code>(<code>gsstate.h</code>)<br><code>gscolor1.h</code><br><code>gscolor2.h</code><br><code>gsht.h</code>(<code>gsht1.h</code>,<code>gsstate.h</code>)<br><code>gsht1.h</code><br><code>gsline.h</code>(<code>gsstate.h</code>)</td> - - <td> </td> - </tr> -<tr> - <td>Coordinate system and matrix</td> - - <td><code>gscoord.h</code><br><code>gsmatrix.h</code></td> - - <td><code>*matrix</code>, <code>*identmatrix</code>, <code>*concatmatrix</code>, <code>*invertmatrix</code></td> - </tr> -<tr> - <td>Path construction</td> - - <td><code>gspath.h</code><br><code>gspath2.h</code></td> - - <td><code>*arct</code>, <code>*pathforall</code>, <code>ustrokepath</code>, <code>uappend</code>, <code>upath</code>, <code>ucache</code></td> - </tr> -<tr> - <td>Painting</td> - - <td><code>gsimage.h</code><br><code>gspaint.h</code><br><code>gspath2.h</code></td> - - <td><code>*image</code>, <code>*colorimage</code>, <code>*imagemask</code>, <code>ufill</code>, <code>ueofill</code>, <code>ustroke</code></td> - </tr> -<tr> - <td>Form and pattern</td> - - <td><code>gscolor2.h</code></td> - - <td><code>execform</code></td> - </tr> -<tr> - <td>Device setup and output</td> - - <td><code>gsdevice.h</code></td> - - <td><code>*showpage</code>, <code>*set</code>/<code>currentpagedevice</code></td> - </tr> -<tr> - <td>Character and font</td> - - <td><code>gschar.h</code><br><code>gsfont.h</code></td> - - <td>*(all the <code>show</code> operators), <code>definefont</code>, <code>undefinefont</code>, <code>findfont</code>, <code>*scalefont</code>, <code>*makefont</code>, <code>selectfont</code>, <code>[Global]FontDirectory</code>, <code>Standard</code>/<code>ISOLatin1Encoding</code>, <code>findencoding</code></td> - </tr> -</table></blockquote> - -<p> -The following procedures from the list above operate differently from their -PostScript operator counterparts, as explained here: - -<dl> -<dt><code>gs_makepattern(gscolor2.h)</code> -<dd>Takes an explicit current color, rather than using the current color in -the graphics state. Takes an explicit allocator for allocating the pattern -implementation. See below for more details on -<code>gs_makepattern</code>. -</dl> - -<dl> -<dt><code>gs_setpattern(gscolor2.h)</code> -<dt><code>gs_setcolor(gscolor2.h)</code> -<dt><code>gs_currentcolor(gscolor2.h)</code> -<dd>Use <code>gs_client_color</code> rather than a set of color -parameter values. See below for more details on -<code>gs_setpattern</code>. -</dl> - -<dl> -<dt><code>gs_currentdash_length/pattern/offset(gsline.h)</code> -<dd>Splits up <code>currentdash</code> into three separate procedures. -</dl> - -<dl> -<dt><code>gs_screen_init/currentpoint/next/install(gsht.h)</code> -<dd>Provide an "enumeration style" interface to <code>setscreen</code>. -(<code>gs_setscreen</code> is also implemented.) -</dl> - -<dl> -<dt><code>gs_rotate/scale/translate(gscoord.h)</code> -<dt><code>gs_[i][d]transform(gscoord.h)</code> -<dd>These always operate on the graphics state CTM. The corresponding -operations on free-standing matrices are in <code>gsmatrix.h</code> and -have different names. -</dl> - -<dl> -<dt><code>gs_path_enum_alloc/init/next/cleanup(gspath.h)</code> -<dd>Provide an "enumeration style" implementation of -<code>pathforall</code>. -</dl> - -<dl> -<dt><code>gs_image_enum_alloc(gsimage.h)</code> -<dt><code>gs_image_init/next/cleanup(gsimage.h)</code> -<dd>Provide an "enumeration style" interface to the equivalent of -<code>image</code>, <code>imagemask</code>, and -<code>colorimage</code>. In the <code>gs_image_t</code>, -<code>ColorSpace</code> provides an explicit color space, rather than -using the current color space in the graphics state; -<code>ImageMask</code> distinguishes <code>imagemask</code> from -<code>[color]image</code>. -</dl> - -<dl> -<dt><code>gs_get/putdeviceparams(gsdevice.h)</code> -<dd>Take a <code>gs_param_list</code> for specifying or receiving the -parameter values. See <code>gsparam.h</code> for more details. -</dl> - -<dl> -<dt><code>gs_show_enum_alloc/release(gschar.h)</code> -<dt><code>gs_xxxshow_[n_]init(gschar.h)</code> -<dt><code>gs_show_next(gschar.h)</code> -<dd>Provide an "enumeration style" interface to writing text. Note that -control returns to the caller if the character must be rasterized. -</dl> - -<p> -This level of the library also implements the following operators from other -sections of the Manual: - -<blockquote><table> -<tr> - <th align="left">Section<br>(operators)</th> - - <th align="left">Headers</th> - - <th align="left">Operators</th> - </tr> -<tr> - <td>Interpreter parameter</td> - - <td><code>gsfont.h</code></td> - - <td><code>cachestatus</code>, <code>setcachelimit</code>, <code>*set/currentcacheparams</code></td> - </tr> -<tr> - <td>Display PostScript</td> - - <td><code>gsstate.h</code></td> - - <td><code>set/currenthalftonephase</code></td> - </tr> -</table></blockquote> - -<p> -In order to obtain the full PostScript Level 2 functionality listed above, -<code>FEATURE_DEVS</code> must be set in the makefile to include at least the following: - -<blockquote><code> -FEATURE_DEVS=patcore.dev cmykcore.dev psl2core.dev dps2core.dev ciecore.dev path1core.dev hsbcore.dev -</code></blockquote> - -<p> -The <code>*lib.mak</code> makefiles mentioned below do not always -include all of these features. - -<p> -Files named <code>gs*.c</code> implement the higher level of the -graphics library. As might be expected, all procedures, variables, and -structures available at this level begin with "<code>gs_</code>". -Structures that appear in these interfaces, but whose definitions may be -hidden from clients, also have names beginning with "<code>gs_</code>", -that is, the prefix, not the implementation, reflects at what level the -abstraction is made available. - -<h3><a name="Patterns"></a>Patterns</h3> - -<p> -Patterns are the most complicated PostScript language objects that the -library API deals with. As in PostScript, defining a pattern color and -using the color are two separate operations. - -<p> -<code>gs_makepattern</code> defines a pattern color. Its arguments are as follows: - -<blockquote><table> -<tr> - <td><code>gs_client_color *</code></td> - - <td>The resulting <code>Pattern</code> color is stored here. This is different from PostScript, which has no color objects <em>per se</em>, and hence returns a modified copy of the dictionary.</td> - </tr> -<tr> - <td><code>const gs_client_pattern *</code></td> - - <td>The analogue of the original <code>Pattern</code> dictionary, described in detail just below.</td> - </tr> -<tr> - <td><code>const gs_matrix *</code></td> - - <td>Corresponds to the matrix argument of the <code>makepattern</code> operator.</td> - </tr> -<tr> - <td><code>gs_state *</code></td> - - <td>The current graphics state.</td> - </tr> -<tr> - <td><code>gs_memory_t *</code></td> - - <td>The allocator to use for allocating the saved data for the - <code>Pattern</code> color. If this is - <code>NULL</code>, <code>gs_makepattern</code> uses the - same allocator that allocated the graphics state. Library - clients should probably always use <code>NULL</code>.</td> -</tr> -</table></blockquote> - -<p> -The <code>gs_client_pattern</code> structure defined in -<code>gscolor2.h</code> corresponds to the <code>Pattern</code> -dictionary that is the argument to the PostScript language -<code>makepattern</code> operator. This structure has one extra member, -<code>void *client_data</code>, which is a place for clients to -store a pointer to additional data for the <code>PaintProc</code>; this -provides the same functionality as putting additional keys in the -<code>Pattern</code> dictionary at the PostScript language level. The -<code>PaintProc</code> is an ordinary C procedure that takes as -parameters a <code>gs_client_color *</code>, which is the -<code>Pattern</code> color that is being used for painting, and a -<code>gs_state *</code>, which is the same graphics state that -would be presented to the <code>PaintProc</code> in PostScript. -Currently the <code>gs_client_color *</code> is always the current -color in the graphics state, but the <code>PaintProc</code> should not -rely on this. The <code>PaintProc</code> can retrieve the -<code>gs_client_pattern *</code> from the -<code>gs_client_color *</code> with the -<code>gs_getpattern</code> procedure, also defined in -<code>gscolor2.h</code>, and from there, it can retrieve the -<code>client_data</code> pointer. - -<p> -The normal way to set a <code>Pattern</code> color is to call -<code>gs_setpattern</code> with the graphics state and with the -<code>gs_client_color</code> returned by <code>gs_makepattern</code>. -After that, one can use <code>gs_setcolor</code> to set further -<code>Pattern</code> colors (colored, or uncolored with the same -underlying color space); the rules are the same as those in PostScript. -Note that for <code>gs_setpattern</code>, the -<code>paint.values</code> in the <code>gs_client_color</code> must be -filled in for uncolored patterns; this corresponds to the additional -arguments for the PostScript <code>setpattern</code> operator in the -uncolored case. - -<p> -There is a special procedure <code>gs_makebitmappattern</code> for creating bitmap-based -patterns. Its API is documented in <code>gscolor2.h</code>; its implementation, in -<code>gspcolor.c</code>, may be useful as an example of a pattern using a particularly -simple <code>PaintProc.</code> - -<h3><a name="Lower_level_API"></a>Lower-level API</h3> - -<p> -Files named <code>gx*.c</code> implement the lower level of the graphics -library. The interfaces at the <code>gx</code> level are less stable, -and expose more of the implementation detail, than those at the -<code>gs</code> level: in particular, the <code>gx</code> interfaces -generally use device coordinates in an internal fixed-point representation, -as opposed to the <code>gs</code> interfaces that use floating point -user coordinates. Named entities at this level begin with -<code>gx_</code>. - -<p> -Files named <code>gz*.c</code> and <code>gz*.h</code> are internal to -the Ghostscript implementation, and are not designed to be called by -clients. - -<hr> - -<h2><a name="Visual_trace"></a>Visual Trace instructions</h2> - -<p> -Visual Trace instructions may be inserted in code to provide debug output in -a graphical form. Graphics Library doesn't provide a rasterisation of the -output, because it is platform dependent. Instead this, client application -shpuld set <code>vd_trace0</code> external variable to Graphics Library, -passing a set of callbacks which provide the rasterization. - -<p> -Visual Trace instructions are defined in <code>vdtrace.h</code>. -Debug output must be opened with <code>vd_get_dc</code> instruction, -which obtains a drawing context for the debug output, and must be closed -with <code>vd_release_dc</code> instruction. After opening the output, -scale, origin and shift to be set for mapping the debugee coordinate space -to window coordinate space. Than painting instructions to be used. -Painting may be either immediate or indirect. - -<p> -Indirect painting uses <code>vd_beg_path</code> before -line output and <code>vd_end_path</code> after line output, -to store a path into a temporary storage. After this -<code>vd_stroke</code> may be used for stroking the path, -or <code>vd_fill</code> may be used for filling the region inside the path. - -<p> -Immediate painting happens when path construction instructions are -involved without <code>vd_beg_path</code> and <code>vd_end_path</code>. -In this case lines and curves are being drawed immediately, when a path construction -instruction is executed. - -<p> -The following table explains the semantics of Visual Trace instructions. -<p> - -<table> - <tr> - <th colspan="3">Visual Trace instructions</th> - </tr> -<tr> - <th align="left">Instruction</th> - - <th align="left">Function</th> - - <th align="left">Parameters</th> - </tr> -<tr> - <td><code>vd_get_dc</code></td> - - <td>Obtain drawing context</td> - - <td><code>-T</code> option flag value, for which the subsequent output is enabled.</td> - </tr> -<tr> - <td><code>vd_release_dc</code></td> - - <td>Release drawing context</td> - - <td> </td> -</tr> -<tr> - <td><code>vd_enabled</code></td> - - <td>Is trace currently enabled ?</td> - - <td></td> - </tr> -<tr> - <td><code>vd_get_size_unscaled_x</code></td> - - <td>Get the horizontal size of the output window in pixels.</td> - - <td></td> - </tr> - <tr><td><code>vd_get_size_unscaled_y</code></td> - - <td>Get the vertical size of the output window in pixels.</td> - - <td></td></tr> -<tr> - <td><code>vd_get_size_caled_x</code></td> - - <td>Get the horizontal size of the output window in debuggee coordinate units.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_get_size_caled_y</code></td> - - <td>Get the vertical size of the output window in debuggee coordinate units.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_get_scale_x</code></td> - - <td>Get the horizontal scale.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_get_scale_y</code></td> - - <td>Get the vertical scale.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_get_origin_x</code></td> - - <td>Get the horizontal position of the draft origin in debuggee coordinate space.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_get_origin_y</code></td> - - <td>Get the vertical position of the draft origin in debuggee coordinate space.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_set_scale(s)</code></td> - - <td>Set isotripic scale.</td> - - <td>Debugee space to window space mapping scale, same for both dimentions.</td> - </tr> -<tr> - <td><code>vd_set_scaleXY(sx,sy)</code></td> - - <td>Set anisotripic scale.</td> - - <td>Debugee space to window space mapping scale, one for each dimention.</td> - </tr> -<tr> - <td><code>vd_set_origin(x,y)</code></td> - - <td>Set the draft origin.</td> - - <td>Origin of the draft in debugee space.</td> - </tr> -<tr> - <td><code>vd_set_shift(x,y)</code></td> - - <td>Set the draft position.</td> - - <td>Position of the draft origin in window space (in pixels).</td> - </tr> -<tr><td><code>vd_set_central_shift</code></td> - - <td>Set the draft position to window center.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_erase(c)</code></td> - - <td>Fill entire window.</td> - - <td>Color to fill.</td> - </tr> -<tr> - <td><code>vd_beg_path</code></td> - - <td>Begin path construction.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_end_path</code></td> - - <td>End path construction.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_moveto(x,y)</code></td> - - <td>Path construction : Set the draft current point.</td> - - <td>Debugee coordinates.</td> - </tr> -<tr> - <td><code>vd_lineto(x,y)</code></td> - - <td>Path construction : Line from current point to specified point.</td> - - <td>Debugee coordinates.</td> - </tr> -<tr> - <td><code>vd_lineto_mupti(p,n)</code></td> - - <td>Path construction : Poliline from current point to specified points.</td> - - <td>Array of points and its size, debugee coordinates.</td> - </tr> -<tr> - <td><code>vd_curveto(x0,y0,x1,y1,x2,y2)</code></td> - - <td>Path construction : Curve (3rd-order Bezier) from current - point to specified point, with specified poles.</td> - - <td>2 poles and the curve ending point, debuggee coordinates.</td> - </tr> -<tr> - <td><code>vd_closepath</code></td> - - <td>Path construction : Close the path (is necessary for filling an area).</td> - - <td></td> - </tr> -<tr> - <td><code>vd_bar(x0,y0,x1,y1,w,c)</code></td> - - <td>Bar from point to point.</td> - - <td>2 points (debugee coordinates), width (in pixels) and color.</td> - </tr> -<tr> - <td><code>vd_square(x0,y0,w,c)</code></td> - - <td>Square with specified center and size.</td> - - <td>The center (debugee coordinates), size (in pixels) and color.</td> - </tr> -<tr> - <td><code>vd_rect(x0,y0,x1,y1,w,c)</code></td> - - <td>Canonic rectangle with specified coordinites.</td> - - <td>Coordinates of boundaries (debugee coordinates), line width (in pixels) and color.</td> - </tr> -<tr> - <td><code>vd_quad(x0,y0,x1,y1,x2,y2,x3,y3,w,c)</code></td> - - <td>Quadrangle with specified coordinites.</td> - - <td>Coordinates of vertices (debugee coordinates), line width (in pixels) and color.</td> - </tr> -<tr> - <td><code>vd_curve(x0,y0,x1,y1,x2,y2,x3,y3,c,w)</code></td> - - <td>Curve with width.</td> - - <td>4 curve poles (debugee coordinates), color, and width (in pixels).</td> - </tr> -<tr> - <td><code>vd_circle(x,y,r,c)</code></td> - - <td>Circle.</td> - - <td>Center (debugee coordinates), radius (in pixels) and color.</td> - </tr> -<tr> - <td><code>vd_round(x,y,r,c)</code></td> - - <td>Filled circle.</td> - - <td>Center (debugee coordinates), radius (in pixels) and color.</td> - </tr> -<tr> - <td><code>vd_stroke</code></td> - - <td>Stroke a path constructed with vd_beg_path, vd_moveto, vd_lineto, - vd_curveto, vd_closepath, vd_end_path.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_fill</code></td> - - <td>Fill a path constructed with vd_beg_path, vd_moveto, vd_lineto, - vd_curveto, vd_closepath, vd_end_path.</td> - - <td></td> - </tr> -<tr> - <td><code>vd_setcolor(c)</code></td> - - <td>Set a color.</td> - - <td>Color (an integer consisting of red, green, blue bytes).</td> - </tr> -<tr> - <td><code>vd_setlinewidth(w)</code></td> - - <td>Set line width.</td> - - <td>Width (in pixels).</td> - </tr> -<tr> - <td><code>vd_text(x,y,s,c)</code></td> - - <td>Paint a text.</td> - - <td>Origin point (debugee coordinates), a string, and a color.</td> - </tr> -<tr> - <td><code>vd_wait</code></td> - - <td>Delay execution until a resuming command is entered through user interface.</td> - - <td></td> - </tr> -</table> - - -<p> -Graphics Library doesn't provide a rasterization of the debug output. -Instead it calls callbacks, which are specified by a client, and which may -have a platform dependent implementation. The implementation must not -use Graphics Library to exclude recursive calls to it from Visual Trace -instructions. The callbacks and auxiliary data are collected in -the structure <code>vd_trace_interface</code>, explained in the table below. -</p> - -<table> -<tr> - <th colspan="3">vd_trace_interface structure</th> - </tr> -<tr> - <th align="left">Field</th> - - <th align="left">Purpose</th> - - <th align="left">Parameters</th> - </tr> -<tr> - <td><code>host</code></td> - - <td>A pointer to the rasterizer control block - to be provided by client application. - The type of the fild is client dependent.</td> - - <td></td> - </tr> -<tr> - <td><code>scale_x, scale_y</code></td> - - <td>Scale of debugee coordinate to window coordinate mapping - internal work data, don't change.</td> - - <td></td> - </tr> -<tr> - <td><code>orig_x, orig_y</code></td> - - <td>Draft origin in debugee coordinates - internal work data, don't change.</td> - - <td></td> - </tr> -<tr> - <td><code>shift_x, shift_y</code></td> - - <td>Draft shift in window coordinates - internal work data, don't change.</td> - - <td></td> - </tr> -<tr> - <td><code>get_size_x(I)</code></td> - - <td>Get window width in pixels.</td> - - <td></td> - </tr> -<tr> - <td><code>get_size_y(I)</code></td> - - <td>Get window height in pixels.</td> - - <td></td> - </tr> -<tr> - <td><code>get_dc(I,I1)</code></td> - - <td>Obtain drawing context.</td> - - <td>Pointer to interface block, and pointer to copy of the pointer. - Implementation must set *I1 if it succeeds to get a drawing context.</td> - </tr> -<tr> - <td><code>release_dc(I,I1)</code></td> - - <td>Release drawing context.</td> - - <td>Pointer to interface block, and pointer to copy of the pointer. - Implementation must reset *I1 if it succeeds to release the drawing context.</td> - </tr> -<tr> - <td><code>erase(I,c)</code></td> - - <td>Erase entire window.</td> - - <td>Background color.</td> - </tr> -<tr> - <td><code>beg_path(I)</code></td> - - <td>Begin path construction.</td> - - <td></td> - </tr> -<tr> - <td><code>end_path(I)</code></td> - - <td>End path construction.</td> - - <td></td> - </tr> -<tr> - <td><code>moveto(I,x,y)</code></td> - - <td>Set current point.</td> - - <td>A point in window coordinates.</td> - </tr> -<tr> - <td><code>lineto(I,x,y)</code></td> - - <td>Line from current point to specified point.</td> - - <td>A point in window coordinates.</td> - </tr> -<tr> - <td><code>curveto(I,x0,y0,x1,y1,x2,y2)</code></td> - - <td>Curve from current point with specified poles to specified point.</td> - - <td>3 points in window coordinates.</td> - </tr> -<tr> - <td><code>closepath(I)</code></td> - - <td>Close the path.</td> - - <td></td> - </tr> -<tr> - <td><code>circle(I,x,y,r)</code></td> - - <td>Circle.</td> - - <td>Center and radius, window coordinates.</td> - </tr> -<tr> - <td><code>round(I,x,y,r)</code></td> - - <td>Filled circle.</td> - - <td>Center and radius, window coordinates.</td> - </tr> -<tr> - <td><code>fill(I)</code></td> - - <td>Fill the path.</td> - - <td></td> - </tr> -<tr> - <td><code>stroke(I)</code></td> - - <td>Stroke the path.</td> - - <td></td> - </tr> -<tr> - <td><code>setcolor(I,c)</code></td> - - <td>Set color.</td> - - <td>An integer, consisting of red, green, blue bytes.</td> - </tr> -<tr> - <td><code>setlinewidth(I,w)</code></td> - - <td>Set line width.</td> - - <td>Line width in pixels.</td> - </tr> -<tr> - <td><code>text(I,x,y,s)</code></td> - - <td>Draw a text.</td> - - <td>Coodrinates in pixels, and a string.</td> - </tr> -<tr> - <td><code>wait(I)</code></td> - - <td>Delay execution untill resume command is inputted from user.</td> - - <td></td> - </tr> -</table> - -<p> -<hr> - -<h2><a name="Full_example"></a>A full example</h2> - -<p> -The file <code>gslib.c</code> in the Ghostscript fileset is a complete -example program that initializes the library and produces output using it; -files named <code>*lib.mak</code> (such as <code>ugcclib.mak</code> -and <code>bclib.mak</code>) are makefiles using <code>gslib.c</code> -as the main program. The following annotated excerpts from this file are -intended to provide a roadmap for applications that call the library. - -<blockquote><pre>/* Capture stdin/out/err before gs.h redefines them. */ -#include <stdio.h> -static FILE *real_stdin, *real_stdout, *real_stderr; -static void -get_real(void) -{ real_stdin = stdin, real_stdout = stdout, real_stderr = stderr; -}</pre></blockquote> - -<p> -Any application using Ghostscript should include the fragment above at the -very beginning of the main program. - -<blockquote><pre>#include "gx.h"</pre></blockquote> - -<p> -The <code>gx.h</code> header includes a wealth of declarations related -to the Ghostscript memory manager, portability machinery, debugging -framework, and other substrate facilities. Any application file that calls -any Ghostscript API functions should probably include <code>gx.h</code>. - -<blockquote><pre>/* Configuration information imported from gconfig.c. */ -extern gx_device *gx_device_list[]; - -/* Other imported procedures */ - /* from gsinit.c */ -extern void gs_lib_init(P1(FILE *)); -extern void gs_lib_finit(P2(int, int)); - /* from gsalloc.c */ -extern gs_ref_memory_t *ialloc_alloc_state(P2(gs_memory_t *, uint));</pre></blockquote> - -<p> -The externs above are needed for initializing the library. - -<blockquote><pre> gs_ref_memory_t *imem; -#define mem ((gs_memory_t *)imem) - gs_state *pgs; - gx_device *dev = gx_device_list[0]; - - gp_init(); - get_real(); - gs_stdin = real_stdin; - gs_stdout = real_stdout; - gs_stderr = real_stderr; - gs_lib_init(stdout); - .... - imem = ialloc_alloc_state(&gs_memory_default, 20000); - imem->space = 0; - .... - pgs = gs_state_alloc(mem);</pre></blockquote> - -<p> -The code above initializes the library and its memory manager. <code>pgs</code> now -points to the graphics state that will be passed to the drawing routines in -the library. - -<blockquote><pre> gs_setdevice_no_erase(pgs, dev); /* can't erase yet */ - { gs_point dpi; - gs_screen_halftone ht; - gs_dtransform(pgs, 72.0, 72.0, &dpi); - ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001; - ht.angle = 0; - ht.spot_function = odsf; - gs_setscreen(pgs, &ht); - }</pre></blockquote> - -<p> -The code above initializes the default device and sets a default halftone -screen. (For brevity, we have omitted the definition of odsf, the spot -function.) - -<blockquote><pre> /* gsave and grestore (among other places) assume that */ - /* there are at least 2 gstates on the graphics stack. */ - /* Ensure that now. */ - gs_gsave(pgs);</pre></blockquote> - -<p> -The call above completes initializing the graphics state. When the program -is finished, it should execute: - -<blockquote><pre> gs_lib_finit(0, 0);</pre></blockquote> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Make.htm b/doc/Make.htm deleted file mode 100644 index 6ed776dd..00000000 --- a/doc/Make.htm +++ /dev/null @@ -1,1459 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>How to Build Ghostscript from Source Code</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>How to Build Ghostscript from Source Code</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#General_overview">General overview</a></li> - <li><a href="#Acquiring">How to acquire the source code</a></li> - <li> - <ul> - <li><a href="#Acquiring_git">How to acquire the development source code</a></li> - </ul> - </li> - <li><a href="#Unpack">How to unpack the source code</a></li> - <li> - <ul> - <li><a href="#Tarfiles">How to unpack compressed tar files generally</a></li> - <li><a href="#Unpack_Ghostscript">How to unpack Ghostscript itself</a></li> - </ul> - </li> - <li><a href="#Bug_check">How to check for post-release bug fixes</a></li> - <li><a href="#Makefile_overview">How to prepare the makefiles</a></li> - <li> - <ul> - <li><a href="#Preparing_makefiles">Changes for your environment</a></li> - <li><a href="#Features_and_devices">Selecting features and devices</a></li> - <li> - <ul> - <li><a href="#Precompiled_data">Precompiled run-time data</a></li> - </ul> - </li> - <li><a href="#Makefile_setup">Setting up "makefile"</a></li> - <li><a href="#MSys/Mingw">MSys/Mingw</a></li> - <li><a href="#Invoke_make">Invoking "make"</a></li> - <li><a href="#Cross-compiling">Cross-compiling</a></li> - </ul> - </li> - <li><a href="#PC_build">How to build Ghostscript from source (PC version)</a></li> - <li> - <ul> - <li><a href="#Microsoft_build">Microsoft environment</a></li> - <li><a href="#Microsoft_build_64">Microsoft environment 64-bit</a></li> - <li><a href="#Microsoft_build_winrt">Microsoft environment WinRT</a></li> - <li><a href="#Self-extracting_executables">Making self-extracting Installers</a></li> - <li><a href="#Cygwin32_build">Cygwin32 gcc</a></li> - </ul> - </li> - <li><a href="#Mac_build">How to build Ghostscript from source (MacOS version)</a></li> - <li> - <ul> - <li><a href="#MacOSX">MacOS X</a></li> - </ul> - </li> - <li><a href="#Unix_build">How to build Ghostscript from source (Unix version)</a></li> - <li> - <ul> - <li><a href="#GNU_make">make tools</a></li> - <li><a href="#OS_specific_issues">OS-specific issues</a></li> - <li> - <ul> - <li><a href="#HP_RISC">H-P RISC workstations</a></li> - <li><a href="#IBMAIX">IBM AIX</a></li> - <li><a href="#Silicon_Graphics">Silicon Graphics</a></li> - <li><a href="#Sun">Oracle/Sun</a></li> - <li><a href="#Solaris">Solaris</a></li> - </ul> - </li> - </ul> - </li> - <li><a href="#Other_environments">Other environments</a></li> - <li> - <ul> - <li><a href="#No_multi_thread">Environments lacking multi-threading</a></li> - <li><a href="#Plan_9">Plan 9</a></li> - </ul> - </li> - <li><a href="#UFST_build">How to build Ghostscript with UFST</a></li> -</ul> - -<!-- [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 instructions on how to <a href="Install.htm">install - Ghostscript</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="General_overview"></a>General overview</h2> - -<p> -This document describes how to build a Ghostscript executable from source -code. There are four major steps to building Ghostscript:</p> - -<ol> -<li>Acquire the compressed archive files of source code for Ghostscript.</li> -<li>Unpack the archive files into the Ghostscript directory.</li> -<li>Configure the build to match your system and desired configuration options.</li> -<li>Invoke "<code>make</code>" to build the software.</li> -</ol> - -<p> -The remainder of this document describes each of these steps in detail. -Note that some of this process is platform-dependent. After building -Ghostscript you must then install it; for that, see the -<a href="Install.htm">installation instructions</a>.</p> -<p> -Long term users of Ghostscript may notice the instructions for a number of -older systems have been removed from this document. There is no value judgment -implied in this, but recognition that the build system has changed considerably -in recent years, and several of these legacy systems are no longer easily -available to the development team. We will always consider contributions to -continue support for legacy systems.</p> -<hr> - -<h2><a name="Acquiring"></a>How to acquire the source code</h2> - -<p> -Building Ghostscript requires the Ghostscript source code itself, and in -some cases the source code for the third-party libraries that -Ghostscript uses.</p> - -<p><a name="Authoritative_distribution_site"></a> -Official releases can be found under the AGPL license at</p> - -<blockquote> -<a href="http://ghostscript.com/download/" -class="offsite">http://ghostscript.com/download/</a> -</blockquote> - -<p> -Ghostscript source code is packaged in gzip-compressed tar archives (*<code>.tar.gz</code>). -(Unlike earlier versions, Ghostscript packages are now one, complete archive, including font files -and third party library dependency sources).</p> - -<blockquote> -<code>ghostscript-</code>#.##<code>.tar.gz</code><br> -</blockquote> - -<p> -("#.##" are version numbers.) -Software to decompress and extract both formats is available for almost -every platform for which Ghostscript is available -- including Unix, Linux, -MS Windows, and so on -- but it's up to you to locate that software. -See the section on <a -href="#Unpack">unpacking the source code</a>.</p> -<hr> -<h2><a name="Acquiring_git"></a>How to acquire the development source code</h2> -<p> -The Ghostscript team use <a href="http://git-scm.com/">git</a> for version -control.</p> -<p> -If you require a snapshot of the development code, the easiest way to get it -is to visit the web interface to our <code>git</code> repository: -<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=summary">ghostpdl.git</a> -and click the "<code>snapshot</code>" link next to the specific commit -in which you are interested. After a short delay, that will download a complete -source tree for the given commit in a <code>gzipped</code> <code>tar</code> -archive.</p> -<p> -If you require access to several commits, or wish to regularly access the -latest development code, you are better to clone the entire <code>git</code> -repository, using:</p> -<blockquote> -<code>git clone git://git.ghostscript.com/ghostpdl.git</code> -</blockquote> -<p>which will create a local, read-only repository.</p> -<p> -Both the "<code>snapshot</code>" and the <code>git clone</code> methods -download the <code>Ghostscript</code> sources as part of the <code>GhostPDL</code> -source tree, which includes the <code>PCL/PXL</code> and <code>XPS</code> -interpreters also built on top of the <code>Ghostscript</code> graphics library.</p> -<p> -The <code>configure</code> script discussed later in the document is created as -part of the <code>Ghostscript</code> release process, and as the source tree -retrieved from <code>git</code> is "pre-release" code, it does not -include a pre-made <code>configure</code> script. See <a href="#autogen_sh">autogen.sh</a></p> -<hr> - -<h2><a name="Unpack"></a>How to unpack the source code</h2> - -<p> -Unfortunately, there are no generally accepted standards for how to package -source code into archives, so the instructions for unpacking Ghostscript are -longer than they should be. We begin with a brief explanation of how to -extract the two kinds of archive files.</p> - -<h3><a name="Tarfiles"></a>How to unpack compressed tar files generally</h3> - -<p> -Tar (<code>.tar</code>) files are the <em>de facto</em> standard for -archiving files on Unix (every Unix-like system has the <code>tar</code> -program), and programs to extract their contents are also widely available -for MS Windows, and most other environments. To economize on space and downloading -time, Ghostscript's tar files are compressed with GNU <code>gzip</code>, which -adds the suffix "<code>.gz</code>" to the file name, giving -"<code>.tar.gz</code>".</p> - -<p> -To unpack a compressed tar file <code>MyArchive.tar.gz</code> you -must both decompress it and extract the contents. You can do this in two -steps, one to decompress the file and another to unpack it:</p> - -<blockquote> -<code>gzip -d MyArchive.tar.gz</code> -<br><code>tar -xf MyArchive.tar</code> -</blockquote> - -<p> -or in a pipeline:</p> - -<blockquote> -<code>gzip -d -c MyArchive.tar.gz | tar -xf -</code> -</blockquote> - -<p> -or, if you have a program like GNU <code>tar</code> that can handle -compressed tar files, with a single command:</p> - -<blockquote> -<code>tar -zxf MyArchive.tar.gz</code> -</blockquote> - -<p> -The <code>tar</code> program automatically preserves directory structure -in extracting files. The Ghostscript source archive puts all files under a -directory <code>ghostscript-</code>#.##, so using <code>tar</code> to unpack a -compressed archive should always properly create that directory, which we -will call the "ghostscript directory". Make sure you're positioned in the -<b><em>parent</em></b> of the ghostscript directory <b><em>before</em></b> unpacking -the files. If a subdirectory doesn't already exist, <code>tar</code> -creates it.</p> -<p> -Some other programs – under MS Windows, for instance – can also unpack -compressed tar files, but they may not automatically preserve directory -structure nor even extract files into the current directory. If you use -one of these, you must</p> - -<ul> - <li>set the program's options to "Use folder names" or the equivalent, and</li> - <li>check that it is extracting files into the right place.</li> -</ul> - -<p> -As both <code>tar</code> and <code>gzip</code> formats are now well supported -by several applications on MS Windows, we only supply the <code>tar.gz</code> archive.</p> - -<blockquote> -<p> -<a href="http://www.winzip.com"> -WinZip</a></p> -<p> -<a href="http://www.7-zip.org/"> -7-zip</a></p> -<p> -<a href="http://www.info-zip.org/"> -Info-ZIP</a></p> -</blockquote> - -<p> -are respectively a commercial and two free applications which can decompress and extract -<code>.tar.gz</code> archives on MS Windows.</p> - -<h3><a name="Unpack_Ghostscript"></a>How to unpack Ghostscript itself</h3> - -<p> -At this point you have <a href="#Acquiring">acquired the source code</a> -and are ready to unpack it according to the <a href="#Tarfiles">preceding guidelines</a>. To unpack the Ghostscript -source, make the <b><em>parent</em></b> of the (new) gs directory the current directory.</p> - -<blockquote><table> -<tr><th align="left" valign="top">2-step:</th> - - <td><code>gzip -d ghostscript-</code>#.##<code>.tar.gz</code><br><code>tar -xf ghostscript-</code>#.##<code>.tar</code></td></tr> -<tr><th align="left" valign="top">Pipe:</th> - - <td><code>gzip -d -c ghostscript-</code>#.##<code>.tar.gz | tar -xf -</code></td></tr> - -<tr><th align="left" valign="top">GNU tar:</th> - - <td><code>tar -zxf ghostscript-</code>#.##<code>.tar.gz</code></td></tr> -</table></blockquote> - -<p> -All the Ghostscript source files are now in subdirectories of the gs -directory.</p> - -<blockquote><table> - <tr><th colspan="2">Ghostscript Core Source subdirectories</th></tr> - <tr><th valign="bottom" align="left">Subdirectory</th> - <th valign="bottom" align="left">Contents</th></tr> - <tr><td><code>arch/</code></td> - - <td>Pre-defined architecture header files</td></tr> - <tr><td><code>base/</code></td> - - <td>Graphics library C source code and makefiles</td></tr> - <tr><td><code>contrib/</code></td> - - <td>Community contributed/supported output devices</td></tr> - <tr><td><code>devices/</code></td> - - <td>The output devices supported by the Ghostscript team</td></tr> - <tr><td><code>psi/</code></td> - - <td>PS interpreter C source code and makefiles</td></tr> - <tr><td><code>Resource/</code></td> - - <td>Postscript initialization, resource and font files</td></tr> - <tr><td><code>lib/</code></td> - - <td>PostScript utilities and scripts used with Ghostscript</td></tr> - <tr><td><code>doc/</code></td> - - <td>Documentation</td></tr> - <tr><td><code>man/</code></td> - - <td>Unix <code>man</code> pages</td></tr> - <tr><td><code>examples/</code></td> - - <td>Sample PostScript files</td></tr> - <tr><td><code>iccprofiles/</code></td> - - <td>Default set of ICC profiles</td></tr> - <tr><td><code>windows/</code></td> - - <td>Visual Studio for Windows specific project and solution files</td></tr> - <tr><td><code>toolbin/</code></td> - - <td>Useful (non-Postscript) tools, mostly for developer use only</td></tr> -</table> -</blockquote> - - <p>Optionally, if you downloaded the GhostPDL archive, you may also have:</p> - -<blockquote><table> -<tr><th colspan=2>Additional GhostPDL source subdirectories</th></tr> - <tr><th valign="bottom" align="left">Subdirectory</th> - - <th valign="bottom" align="left">Contents</th></tr> - <tr><td><code>pcl/</code></td> - - <td>PCL/PXL interpreter C source code, makefiles, fonts etc</td></tr> - <tr><td><code>xps/</code></td> - - <td>XPS interpreter C source code and makefiles</td></tr> -</table> -</blockquote> - -<p>Supporting third party libraries will also be in their own sub-directories (e.g. <code>jpeg</code>, <code>freetype</code> and so on).</p> - -<hr> - -<h2><a name="Bug_check"></a>How to check for post-release bug fixes</h2> - -<p> -Bug information and fixes are tracked on Ghostscript Bugzilla. -For more information, please visit</p> - -<blockquote> -<a href="http://bugs.ghostscript.com"> -http://bugs.ghostscript.com</a> -</blockquote> - -<hr> - -<h2><a name="Makefile_overview"></a>How to prepare the makefiles</h2> - -<p> -The Ghostscript makefiles are very large and complex in order to deal with -the diverse requirements of all the different systems where they may be -used.</p> - -<p> -Ghostscript has an automatic configuration script. If you're on unix or -a system that supports unix shell scripts, this is the easiest option to use. -Simply type:</p> - -<blockquote> -<code>./configure</code> -</blockquote> - -<p>from the top level of the ghostscript source directory. It should configure -itself based on what's available on your system, warn you of any missing -dependencies, and generate a Makefile. At this point you can skip to the -section <a href="#Invoke_make">invoking make</a> below. Also, many common -configuration options (like install location) can be set through options -to the configure script.</p> - -<p> -Type '<code>./configure --help</code>' for a complete -listing. Note that the configuration option is only available with the -unix .tar distributions of the source.</p> - -<p> -Note that if you're building Ghostscript from development source out of -a repository instead of from a released source package, you should run -'<code>./autogen.sh</code>' instead of <code>./configure.</code> This script -takes all the same options that configure does.</p> - -<p> -If your system doesn't support the configure script or you don't wish to -use it, you can use the traditional ghostscript makefile system, editing -the options by hand to match your system as described below. -Fortunately, the only makefiles you're likely to want to change are -relatively small ones containing platform-specific information.</p> - -<blockquote><a name="Platform-specific_makefiles"></a><table> - <tr><th colspan="2">Platform-specific makefiles</th></tr> - <tr><th align="left">Makefile</th> - - <th align="left">Used for</th></tr> - <tr><td><code>Makefile.in</code></td> - - <td>Template makefile for the autoconf build</td></tr> - <tr><td><code>psi/msvc.mak</code></td> - - <td>MS Windows with Microsoft Visual Studio 2003 and later.</td></tr> - <tr><td><code>base/unix-gcc.mak</code></td> - - <td>Unix with gcc</td></tr> - <tr><td><code>base/unixansi.mak</code></td> - - <td>Unix with ANSI C compilers other than gcc</td></tr> -</table> -</blockquote> - -<p> -A number of platform indepdent makefiles in each of the core Ghostscript source directories. -Since these files can change from one Ghostscript version to another, sometimes -substantially, and since they all include documentation for the various -options, here we don't duplicate most of that documentation: we recommend -strongly that you review the entire makefile specific for your operating -system and compiler before building Ghostscript.</p> - -<h3><a name="Preparing_makefiles"></a>Changes for your environment</h3> - -<p> -Assuming you have opted not to use the <code>configure</code> script or -the default Microsoft Visual Studio bulid, you must -edit the platform-specific makefile to change any of these:</p> - -<ul> -<li>The name of the makefile itself (<code>MAKEFILE</code> macro)</li> -<li>The locations to install Ghostscript files (<code>prefix</code> etc.)</li> -<li>The default search paths for the initialization and font files -(<code>GS_LIB_DEFAULT</code> macro)</li> -<li>The debugging options (<code>DEBUG</code> and <code>TDEBUG</code> -macros)</li> -<li>Which optional features to include (<code>FEATURE_DEVS</code>)</li> -<li>Which device drivers to include (<code>DEVICE_DEVS</code> and -<code>DEVICE_DEVS</code>{<em>1--20</em>} macros)</li> -<li>Default resolution parameters for some printer drivers -(<code>devs.mak</code> or <code>contrib.mak</code>, whichever defines -the driver)</li> -</ul> -<p> In general these will be set to commonly sensible values already, but -may not be ideal for your specific case.</p> - -<p> -The <a href="#Platform-specific_makefiles">platform-specific makefiles</a> -include comments describing all these except the -<code>DEVICE_DEVS</code> options. These are described in -<code>devs.mak</code> and <code>contrib.mak</code>, even though the -file that must be edited to select them is the <a -href="#Platform-specific_makefiles">platform-specific makefile</a>.</p> - -<p> -Some platform-specific options are described in the sections for individual -platforms. See the "Options" section near the beginning of the relevant -makefile for more information.</p> - -<h3><a name="Features_and_devices"></a>Selecting features and devices</h3> - -<p> -You may build Ghostscript with any of a variety of features and with any -subset of the available device drivers. The complete list of features is -in a comment at the beginning of <code>gs.mak</code>, and the complete -list of drivers in comments at the beginning of <code>devs.mak</code> -and <code>contrib.mak</code>. To find what devices a platform-specific -makefile selects to include in the executable, look in it for all lines of -the form</p> - -<blockquote> -<code>FEATURE_DEVS=</code><em>{list of features}</em><br> -<code>DEVICE_DEVS</code>*<code>=</code><em>{list of devices}</em> -</blockquote> - -<p> -For example, if the makefile has</p> - -<blockquote><code> -FEATURE_DEVS=$(PSD)level2.dev -</code></blockquote> - -<p> -indicating that only the PostScript Level 2 facilities should be included, -you might make it</p> - -<blockquote><code> -FEATURE_DEVS=$(PSD)level2.dev $(PSD)pdf.dev -</code></blockquote> - -<p> -to add the ability to interpret PDF files. (In fact, -<code>FEATURE_DEVS</code> in the current Unix makefiles already includes -<code>$(PSD)pdf.dev</code>.).</p> - -<p> -It is extremely important that FEATURE_DEVS is set correctly. Currently, -the default builds will include a complete feature set, and as such most -of those building Ghostscript will have no need to change it. Only those -working in heavily resource constrained environment will want to experiment, -and it is vital that the implications of such changes be understood, otherwise -Ghostscript may behave in unexpected or apparently incorrect ways, or may -even fail to build.</p> - -<p> -The Unix makefile also defines</p> - -<blockquote><code> -DEVICE_DEVS=$(DD)x11.dev -</code></blockquote> - -<p> -indicating that the X Windows driver should be included, but since -platform-specific makefiles as distributed normally include many of the -possible features and drivers, you will probably rather remove from the -makefile the features and drivers you don't want. It does no harm to -include unneeded features and devices, but the resulting executable will be -larger than needed.</p> - -<p> -You may edit the <code>FEATURE_DEVS</code> line to select or omit any of -the features listed near the beginning of <code>gs.mak</code>, and the -<code>DEVICE_DEVS</code>* lines to select or omit any of the device -drivers listed near the beginning of <code>devs.mak</code> and -<code>contrib.mak</code>. GS_DEV_DEFAULT is a string containing whitespace -separate device names, and give the devices Ghostscript should attempt to use -(and the order) if no device is specified on the command line; -see the usage documentation for <a href="Use.htm#Output_device">how to -select an output device</a> at run time using the -<a href="Use.htm#DEVICE_switch"><code>-sDEVICE=</code></a> switch. If -you can't fit all the devices on a single line, you may add lines defining</p> - -<blockquote> -<code>DEVICE_DEVS1=$(DD)</code><em>{dev11}</em><code>.dev</code> ... <code>$(DD)</code><em>{dev1n}</em><code>.dev</code> -<br><code>DEVICE_DEVS2=$(DD)</code><em>{dev21}</em><code>.dev</code> ... <code>$(DD)</code><em>{dev2n}</em><code>.dev</code> -</blockquote> - -<p> -etc., up to <code>DEVICE_DEVS15</code>. Don't use continuation lines -- -on some platforms they don't work.</p> - -<p> -Note that if you want to include a driver named <em>xxx</em>, you must put -<code>$(DD)</code><em>xxx</em><code>.dev</code> in -<code>DEVICE_DEVS</code>*. Similarly, if you want to include a feature -related to the PostScript or PDF language interpreters (PostScript level -1 .. 3, or other language features such as the ability to read EPSF files or -TrueType font files), you must represent it as -<code>$(PSD)</code><em>xxx</em><code>.dev</code>.</p> - -<h4><a name="Precompiled_data"></a>Precompiled run-time data</h4> - -<p> -Ghostscript normally reads a number of external data files at run time: -initialization files containing PostScript code, fonts, and other resources -such as halftones. By changing options in the top-level makefile for the -platform, you can cause some of these files to be compiled into the -executable: this simplifies installation, improves -security, may reduce memory requirements, and may be essential if you are -planning on putting Ghostscript into ROM. Compiling these files into the executable -also means the executable is (largely) self-contained, meaning initialization -files, font files, resource files and ICC profile files are certain to be available -and accessible. In general, Ghostscript should initialize more quickly, and files -(especially PDF) files making heavy use of the built-in fonts will interpret more -quickly.</p> -<p> -For those distributing Ghostscript binaries, compiling those files into the executable -has another implication, any site-specific customizations (such as font and CIDFont -substitutions) are slightly more complex to implement - see:</p> -<blockquote> -<a href="Use.htm#Finding_files">How Ghostscript finds files</a> -</blockquote> -<p>for how to influence where Ghostscript searches for files. Furthermore, if the files -Ghostscript uses are also required to be accessible by applications other than Ghostscript -(the mostly case for this would be font files and ICC profile files), having those files -compiled into Ghostscript maybe suboptimal, essentially require two copies of the file -data to be distributed (one set built into Ghostscript, and the other as "normal" files -accessible outside of Ghostscript.</p> - -<p> -Compiling the initialization files (<code>Resource/Init/gs_init.ps</code>, etc.) -into the executable is the default. To disable this, change the <code>1</code> to -a <code>0</code> in the line</p> - -<blockquote><code> -COMPILE_INITS=1 -</code></blockquote> - -<p> -Or, if you use the <code>configure</code> based Unix-style build, you can disable -COMPILE_INITS by adding the option <code>--disable-compile-inits</code> to the invocation -of <code>configure</code></p> -<p> -Files are now compiled into the executable as a %rom% file system that can -be searched, opened, etc. as with the normal (%os%) file system. The data -is (mostly) compressed. Several of the initialisation files (those in <code>Resource/Init</code>) -are also converted to binary Postscript encoding, and "merged" into a single monolithic -file - this is done for both size and speed optimization. Files that are often customized for -individual installations (such as <code>Fontmap</code> and <code>cidfmap</code>) are not -merged into the single file and thus installation specific versions can be used.</p> -<p> -The set of files built into the %rom% file system -is specified in the <code>psi/psromfs.mak</code> file. By default the set -of files built into the rom file system comprises all the resource files -Ghostscript requires to run successfully (all the files under <code>Resource</code> -directory, and those under the <code>iccprofiles</code> directory). Refer to the file -<code>base/mkromfs.c</code> for a description of the parameters that -control source and destination pathnames, file enumeration exclusion, -compression, etc.</p> - -<p> -Fonts normally are compiled into the executable using <code>mkromfs</code> -(above) from the Resource/Font/ directory.</p> - -<p> -Similarly, Halftone resources can be compiled into the executable using -<code>mkromfs</code>, but also threshold-array halftones can be compiled -into the executable. See the "Compiled halftone" section of <code>int.mak</code> -for a sample makefile fragment, <code>genht.c</code> for the syntax of -halftone data files, and <code>lib/ht_ccsto.ps</code> for a sample data file. - Note that even though the data files use PostScript syntax, compiled halftones -do not require the PostScript interpreter and may be used with the graphics -library alone.</p> - -<h3><a name="Makefile_setup"></a>Setting up "makefile"</h3> - -<p> -After going through the steps just described to <a href="#Unpack">unpack -the sources</a>, configure the build and make any desired -<a href="#Preparing_makefiles">changes to the makefiles</a>. -As the final step in preparing to build Ghostscript you must usually -associate the name "<code>makefile</code>" with the correct makefile -for your environment so the <code>make</code> command can find it. -See the section on your particular platform for how to do that if -necessary.</p> - -<p> -On unix systems, <code>./configure</code> (or if checked out of git, -<code>./autogen.sh</code>) should create a <code>Makefile</code> which works -in most scenarios. Manual tampering and editing should rarely be needed -nor recommended.</p> - -<h3><a name="Invoke_make"></a>Invoking "make"</h3> - -<dl> - <dt><code>make</code></dt> - <dd>Builds Ghostscript without debugging options.</dd> -</dl> - -<dl> - <dt><a name="Debugging"></a><code>make debug</code></dt> -<dd>Builds Ghostscript with debugging options and additional internal error -checks. The program will be somewhat larger and slower, but it will behave -no differently unless you actually turn on debugging options at execution -time with the <code>-DDEBUG</code> or -<a href="Use.htm#Debugging"><code>-Z</code> command line switches</a> - described in the usage documentation.</dd> -</dl> - -<dl> - <dt><code>make pg</code></dt> -<dd>On Unix platforms, builds with the <code>-pg</code> compiler - switch, creating an executable for time profiling.</dd> -</dl> - -<dl> - <dt><code>make install</code></dt> - <dd>After building, installs the Ghostscript executables, support files, - and documentation, but does <b><em>not</em></b> install fonts. See the - <a href="Install.htm">installation documentation</a>.</dd> -</dl> - -<dl> - <dt><code>make (debug)clean</code></dt> - <dd>Deletes all the files created by the build process (relocatables, - executables, and miscellaneous temporary files). If you've built an - executable and want to save it, move it first to another place, because - "<code>make clean</code>" deletes it.</dd> -</dl> - -<dl> - <dt><code>make so</code></dt> - <dd>On some platforms (Linux, *BSD, Darwin/Mac OS X, SunOS), - it is possible to build Ghostscript as a shared object library. - There is a corresponding "<code>make soclean</code>" for cleaning up.</dd> -</dl> - -<dl> - <dt><code>make sanitize</code></dt> - <dd>Builds Ghostscript with AddressSanitizer. Output is placed in ./sanbin .</dd> -</dl> - -<p> -<b><em>Note:</em></b> on most platforms some of these simple instructions don't -quite work in one way or another. Read the section on your specific -platform.</p> - -<p> -<b><em>Note 2:</em></b> If you are attempting to build a statically linked -executable, you will probably need to add libraries to the linker options -(libraries that are normally pulled-in automatically by the dynamic linker). -These can be added at the make command line using the "EXTRALIBS=" option. -Unfortunately, the set of libraries that may be required varies greatly -depending on platform and configuration, so it is not practical to offer -a list here.</p> - -<h3><a name="Cross-compiling"></a>Cross-compiling</h3> -<p> -Cross-compiling is not fully supported by the <code>configure</code> script (such -support is a work-in-progress).</p> -<p> -You can either use <code>base/unixansi.mak</code> or <code>unix-gcc.mak</code> -as the basis for a cross-compile makefile, or use <code>configure</code> to -create a basic <code>Makefile</code> as the basis. And modify to suit.</p> -<p> -You can set the compiler to your cross-compiler for <code>configure</code> by doing:</p> -<blockquote> -./configure CC=<cross-compiler executable> -</blockquote> -<p> -and <code>configure</code> will then run its checks (as best it can) with the -cross-compiler.</p> -<p> -If you do so, you should also give <code>configure</code> the option to set the -target architecture endianness: <code>--enable-big-endian</code> or <code>--enable-little-endian</code>.</p> -<p> -It would also be wise to review the settings shown in the output of <code>./configure --help</code> for -any that would be applicable to your target.</p> -<br> -<br> -<p> -The Ghostscript build system uses several interim executables, built and run on the <code>host</code>, -as such, even when cross-compiling, a <code>host native</code> compiler is also required. You must edit -your <code>makefile</code> to ensure that is available. Find the line that starts:</p> -<blockquote> -CCAUX= -</blockquote> -<p> -and set that to your <code>host compiler</code>.</p> -<p> -If you did not use <code>configure</code> or did not set the <code>CC</code> variable for <code>configure</code>, -you must also set the:</p> -<blockquote> -CC= -</blockquote> -<p> -to your cross-compiler.</p> -<p> -The Ghostscript build system uses a utility called <code>genarch</code> -(see <code>base/genarch.c</code> for details) to interrogate the environment and -generate a header file describing the architecture for which Ghostscript is being -built. As this is run on the <code>host</code> it will generate header for the -<code>host architecture</code> rather than that of the <code>target</code>.</p> -<p> -For cross compiling, you must create (or modify) a header file (<code>arch.h</code>) -which accurately describes the <code>target architecture</code>. Then you must -edit your <code>makefile</code> by finding the line:</p> -<blockquote> -TARGET_ARCH_FILE= -</blockquote> -<p> -and set it to the path to, and file name of your custom <code>arch.h</code> file. With that -setting, <code>genarch</code> will still be run, but rather than interrogate the current environment, -it will copy the contents of your custom <code>arch.h</code> to the build.</p> - -<hr> - -<h2><a name="PC_build"></a>How to build Ghostscript from source (PC version)</h2> - -<p> -All Ghostscript builds in PC (DOS and MS Windows) environments are 32- or -64-bit: 16-bit builds are not supported. The relevant makefiles are</p> - -<blockquote><table> - <tr><th colspan="3">PC makefiles</th></tr> - <tr><th align="left">Makefile</th> - - <th align="left">Construction tools</th> - - <th align="left">For environment</th></tr> - <tr><td valign="top"><code>msvc.mak</code></td> - - <td valign="top"><a href="#Microsoft_build">Microsoft Visual Studio .NET 2003 (or later)</a></td> - - <td valign="top">MS Windows 32/64-bit</td></tr> - <tr><td valign="top"><code>Makefile.in</code></td> - - <td valign="top"><a href="#Cygwin_build">Cygwin/gcc</a></td> - - <td valign="top"><a href="https://www.cygwin.com/">Cygwin</a> (Use Unix <code>configure</code>)</td></tr> -</table></blockquote> - -<p> -Ghostscript requires at least MS Windows 95 (although we no longer actively test nor -support Win95, we have not deliverately done anything to break compatibility with it). -We recommend at least MS Windows NT 4.0.</p> -<p> -For building, Ghostscript requires at least Visual Studio .NET 2003, and we recommend -at least Visual Studio 2005 (required for 64 bit Windows support).</p> -<p> -Note that the <code>make</code> program supplied with Visual Studio (and earlier -Visual C++ versions) is actually called <code>nmake</code>. We refer to this -program generically as <code>make</code> everywhere else in this document.</p> - -<p> -You must have <code>cmd.exe</code> in your path to build Ghostscript (using -the Visual Studio command prompt is ideal). After making any changes required to choose -features and devices to build into the executable, you can then invoke <code>make</code> -to build the executable.</p> - -<p><a name="Make_windows"></a></p> - -<h3><a name="Microsoft_build"></a>Microsoft Visual Studio</h3> - -<h4><a name="Using_the_MS_Development_Environment"> </a><u>Using Microsoft Visual Studio</u></h4> -<p> -The Ghostscript source distribution ships with <code>project</code> and <code>solution</code> -files for Visual Studio 2005 and later. These can be found in the <code>windows</code> directory. -The <code>project(s)</code> are <code>nmake projects</code> which means that rather than Visual -Studio controlling the build directly, it delegates the build process the the <code>nmake</code>.</p> -<p> -Beyond lacking support for parallel builds (<code>nmake</code> cannot support parallel builds), -there should be little visible difference between a conventional VS project and an -<code>nmake project</code> to the user of the VS graphical interface. The only exception to that -is if you have to make changes to build options beyond those available in the defined build -configurations. In that case, you need to find the <code>Nmake</code> tab in the project -<code>Property Pages</code> and modify the appropriate entry: <code>Build Command Line</code>, -<code>Rebuild All Command Line</code> and/or <code>Clean Command Line</code>.</p> -<p> -As mentioned above, <code>nmake</code> does not support parallel builds. If you -have downloaded and are building the <code>GhostPDL</code> source archive (which contains -Ghostscript, GhostPCL, GhostXPS, and GhostPDL "products"), the <code>GhostPDL.sln</code> -contains individual projects for each product but, as a result of the limitations of <code>nmake</code> -the products cannot be built in parallel, because <code>nmake's</code> lack of parallel build -awareness means it cannot manage the dependencies shared between the products, and may fail as multiple -builds attempt to access the same dependencies. -<p> To build all the products in one action, use the <code>All</code> "pseudo-project". The -<code>All</code> project uses a single <code>nmake</code> invocation to build all the supported products. -<p> -NOTE: changing the <code>Output</code> property in the <code>Nmake</code> properties will not -change the name of the executable - to do that requires editing of the <code>psi/msvc.mak</code> -makefile, or you can add: <code>GS=myname.exe</code> to the <code>nmake</code> command line.</p> - -<h4><a name="Using_the_command_line"></a>Using the command line</h4> -<p>Ghostscript can be made using the Windows command prompt or one of the various command -line shells made for Windows, as long as the command line syntax is compatible with the -Windows <code>CMD.exe</code>. The Visual Studio command prompt is ideal.</p> - -<p>In order for the makefiles to work properly, two items may have to be changed. - An attempt is made to select the correct version of Microsoft Visual C++ - based on the version of nmake. If this doesn't work it will default - to version 6.x. - If the auto-detection does not work, and you are not using version 6.x then before building, - in <code>psi\msvc.mak</code> find the line "<code>#MSVC_VERSION=6</code>" and change it to - "<code>MSVC_VERSION=4</code>", "<code>MSVC_VERSION=5</code>", "<code>MSVC_VERSION=7</code>" - or "<code>MSVC_VERSION=8</code>" and so on. </p> -<p>In some cases the location of the Microsoft Developer Studio, needs to be changed. - The location of Microsoft Developer Studio is defined by the value of <code>DEVSTUDIO</code>. - There are several different definitions of <code>DEVSTUDIO</code> in psi\msvc.mak. - There is one for each of the currently supported versions of Microsoft Visual - C++ (4, 5, 6, 7, 7.1 and 8). </p> -<p>The normal installation process for Microsoft Visual C++ includes setting the - location of the Microsoft Visual C++ executables (cl.exe, link.exe, nmake.exe, - rc.exe) in your PATH definition and the LIB and INCLUDE environment variables - are set to point to the Microsoft Visual C++ directories. If this is true then - the value for <code>DEVSTUDIO</code> can be changed to empty. I.e. <code>DEVSTUDIO=</code></p> -<p> If PATH, LIB, and INCLUDE are not correctly set then the value for <code>DEVSTUDIO</code> - needs to be defined. For example, for version 6.0, the default definition for - the location for the Microsoft Developer Studio is: <code>DEVSTUDIO=C:\Program - Files\Microsoft Visual Studio </code> If the path to Microsoft Developer Studio - on your system differs from the default then change the appropriate definition - of <code>DEVSTUDIO</code>. (Remember that there is a separate definition - of <code>DEVSTUDIO</code> for each version of MSVC, so be sure to change - the correct definition.) </p> -<p>To run the <code>make</code> program, give the command </p> -<blockquote><code> -nmake -f psi\msvc.mak -</code></blockquote> - -<p> -Rather than changing psi/msvc.mak, these values can also be specified on -the make command line, I.e.</p> - -<blockquote><code> nmake -f psi\msvc.mak MSVC_VERSION=6 DEVSTUDIO="C:\Program Files\Microsoft Visual Studio" <br> -nmake -f psi\msvc.mak MSVC_VERSION=7 DEVSTUDIO="C:\Program Files\Microsoft Visual Studio .NET" - </code></blockquote> - -<p> Note that double quotes have been added around the path for <code>DEVSTUDIO</code> - due to the spaces in the path value.</p> -<p> -This command line can also be put into a batch file.</p> - -<p> You may get warning messages during compilation about various undefined -and/or unsupported switches - this is because the compiler switches are set -in the makefiles, and are applied when building with all versions of Visual -Studio, but not all options are supported (or required) by all versions of -Visual Studio. These warnings are benign and can be ignored.</p> - -<h3><a name="Microsoft_build_64"></a>Microsoft Environment for 64-bit</h3> - -<p>Building Ghostscript for 64-bit Windows (AMD64 processor) requires -Microsoft Visual Studio .NET 2005 or Microsoft Visual Studio 2008 or later -on 64-bit Windows. Cross compiling on 32-bit Windows is possible.</p> -<p> -Compiling for 64-bit is similar to the -<a href="#Microsoft_build">Microsoft Environment</a> instructions above, -but with the addition of a WIN64 define.</p> - -<p>To make ghostscript use</p> -<blockquote><code> - nmake -f psi/msvc.mak WIN64= -</code></blockquote> - -<h4><a name="Self-extracting_executables"></a>Making self-extracting installers</h4> - -<p> -You can build self-extracting Windows installers based on -<code>NSIS (Nullsoft Scriptable Install System)</code>. To do so, use the <code>nsis</code> -makefile taget as well as any other options, for example:</p> -<blockquote><code> - nmake -f psi/msvc.mak WIN64= nsis -</code></blockquote> -<p> -will create an <code>nsis</code> based installer for Ghostscript built for 64 bit Windows -systems.</p> - -<h3><a name="Microsoft_build_winrt"></a>Microsoft Environment for WinRT</h3> - -<p> -Ghostscript can be built in the form of a win32 DLL for use within a Windows Runtime -application or Windows Runtime component. Building for WinRT requires use of -Microsoft Visual Studio 2012. There is a solution file that can be loaded into VS 2012, -in the directory <code>winrt</code></p> - -<p> -The WinRT application or component should include <code>iapi.h</code> from -<code>gs/psi</code> and link with <code>gsdll32metro.lib</code> from -<code>gs/debugbin</code> or <code>gs/releasebin</code>. Also any app using -ghostscript either directly or via a component should add <code>gsdll32metro.dll</code> -as "content". This inclusion of the dll is necessary so that it -will be packaged with the app. If one wishes to be able to run the debugger on -ghostscript then <code>gsdll32metro.pdb</code> should also be added as content.</p> - -<h3><a name="Cygwin32_build"></a>Cygwin32 gcc</h3> - -<p> -It is possible to compile Ghostscript for MS Windows using the Cygwin32 gcc compiler, -GNU <code>make</code>, using the "configure" generated Makefile.</p> - -<p> -Information about this compiler and environment is at the Cygwin site:</p> - -<blockquote> -<a href="http://www.cygwin.com/">http://www.cygwin.com/</a> -</blockquote> - -<h4><a name="MSys/Mingw"></a>MSys/Mingw</h4> -<p>The configure build can be used to build Ghostscript on MSys/Mingw systems, -but with a caveat. The msys-dvlpr adds header files into the compiler's header -search paths which cause a clash, and the build will fail as a result. If you -have the msys-dvlpr package installed, and until a better solution is available -you can work around this by temporarily renaming the "\mingw\msys\1.0\include" -directory so those headers are no longer found by the compiler.</p> - -<hr> - -<h2><a name="Mac_build"></a>How to build Ghostscript from source (MacOS version)</h2> - -<h3><a name="MacOSX"></a>MacOS X</h3> - -<p> -The unix source distribution (.tar.gz) builds fine on Darwin/MacOS X, -albeit without a display device. You can generally just use the <tt>Makefile</tt> -generated by <tt>configure</tt> as your top-level makefile and get a reasonable default -build. This will allow you to use Ghostscript from the command line as a BSD-layer -tool to rasterize postscript and pdf to image files, and convert between the -high-level formats supported by Ghostscript. See the instructions for the -unix build below for details of how to customize this build.</p> -<p> -NOTE: If you have MacPorts (http://www.macports.org/) installed, it can -"confuse" the configure script because it includes some librares which -duplicate the "system" ones. This can cause missing symbol link errors. -In order to resolve this, you can do:<code> LDFLAGS="-L/usr/lib" ./configure</code>. -That will force the linker to search the default directory first, and thus pick -up the system libraries first.</p> -<p> -It is also possible to build "universal binaries" for MacOS X, containing <code>i386</code> -and <code>x86_64</code> binaries in one file, using the <code>Makefile</code> -from <code>configure</code>. This can be achieved by using the following invokation of -<code>configure</code></p> -<blockquote> -<code> -./configure CC="gcc -arch i386 -arch x86_64 -arch ppc" CPP="gcc -E" -</code> -</blockquote> -<p> -You can choose the combination of valid architectures (i386/x86_64/ppc) that you -require.</p> -<p> -The separate options for <tt>CC</tt> and <tt>CPP</tt> are required because some of -the features used by <tt>configure</tt> to explore the capabilities of the preprocessor -are not compatible with having multiple <tt>-arch</tt> options.</p> -<p> -Building a shared library on MacOS X is the same as for other Unix-like systems, the -"configure" step is done normally, and the "so" target is given to the make invocation, -thus:</p> -<blockquote> -<code> -make so -</code> -</blockquote> -<p>The only difference compared to other Unix-like systems is that on OS X the resulting -shared library is created with the ".dylib" file name extension, instead of the more -usual ".so".</p> - -<hr> - -<h2><a name="Unix_build"></a>How to build Ghostscript from source (Unix version)</h2> - -<p> -Ghostscript now ships with a build system for unix-like operating systems -based on GNU Autoconf. In general the following should work to configure -and build Ghostscript:</p> - -<blockquote><pre> -./configure -make -</pre></blockquote> - -<p>or</p> - -<blockquote><pre> -./configure -make so -</pre></blockquote> - -<p>for building ghostscript as a shared library.</p> - -<p>Please report any problems with this method on your system as a bug.</p> - -<p> -On modern unix systems, <code>./configure</code> -should create a <code>Makefile</code> which works -in most scenarios. Manual tempering and editing should rarely be needed -nor recommended.</p> - -<p> -<a name="autogen_sh"></a> -Note that if you're building Ghostscript from development source out of -a repository instead of from a released source package, you should run -'<code>./autogen.sh</code>' instead of <code>./configure.</code> This script -takes all the same options that configure does.</p> - -<p> -(deprecated; see Autoconf-based method above) -For the convenience of those already familiar with Ghostscript, the old method -based on hand-edited makefiles is still possible but no longer supported -(and in many cases, simply do not work without substantial -expert manual-editing effort). It may also be helpful in -getting Ghostscript to build on very old platforms. The rest of this section deals exclusively -with that older method and includes numerous pointers regarding legacy systems.</p> - -<p> -(deprecated; see Autoconf-based method above) -Before issuing the <code>make</code> command to build Ghostscript, you -have to make some choices, for instance</p> -<ul> - <li>which compiler to use;</li> -<li>what features and devices to include;</li> -<li>whether to use system libraries for PNG and zlib;</li> -<li>and how to handle issues for your particular platform.</li> -</ul> - -<p> -Be sure to check the sections on <a -href="#Tool_specific_issues">tool-</a>, <a -href="#OS_specific_issues">OS-</a>, and <a -href="#Hardware_specific_issues">hardware-</a>specific issues for notes -on your particular platform and compiler. In fact, that is the -<b><em>first</em></b> place to check if you build Ghostscript and it crashes - or produces obviously incorrect results.</p> - -<h3><a name="GNU_make"></a>make tools</h3> - -<p> -You require a make tool which supports separate directories for -the derived objects (such as object files, executables and dynamically created -header files) and the source files.</p> -<p> -In general, GNU make is the recommended choice, and some features (such as the -building of the Linux/Unix shared library build ("make so") are only available -with GNU make.</p> -<p> -Other <code>make</code> implementations are known to work, but are not guaranteed -to do so.</p> -<p> -<u><a name="GNU_make"></a>GNU make</u></p> -<p> -Current versions of GNU <code>make</code> have no problems building -Ghostscript.</p> - -<h3><a name="OS_specific_issues"></a>OS-specific issues</h3> - - -<h4><a name="HP_RISC"></a>H-P RISC workstations</h4> - - - -<p> -(see Autoconf-based method above)</p> -<ul> -<li>HP-UX versions before 11.0 do not support POSIX threads. Set - <code>SYNC=nosync</code> in the makefile before building.</li> - -<li>Ghostscript builds on H-P machines with either GNU gcc or H-P's -ANSI-capable <code>cc</code>. The minimal, non-ANSI-capable -<code>cc</code> that shiped with some basic HPUX system does <em>not</em> -work. If <code>cc</code> on your system doesn't accept the -<code>-Aa</code> switch, then you need to get the full -<code>cc</code> or gcc.</li> - -<li>If you use H-P's compiler, be sure you have upgraded to a recent -release. Many bizarre symptoms have been reported trying to build -Ghostscript with older, buggier compilers, for example:</li> - -<li> -<ul> -<li>The link step fails with a message about "<code>max</code>" not being defined.</li> -<li>The build succeeds, but the resulting executable fails to start up, -with an error message like "Initializing... Unrecoverable error: typecheck -in .registerencoding".</li> -<li>The build succeeds, but the resulting executable produces a black -background on the first page of output.</li> -</ul> -</li> - -<li>It is reported that On HPUX 9.* you need at least compiler patch -PHSS_5723 and dld.sl patch PHSS_5734 to build Ghostscript. (As of late -1997, those patches are long obsolete; the current patches are compiler -PHSS_10357 and dld.sl PHSS_11246. It is unknown whether current -Ghostscript releases work with compiler/dld.sl versions older than these.)</li> - -<li>On HPUX 10.*, we don't know what combinations of compiler version and -switches work. It is reported that On HPUX 10.20, setting -"<code>CC=c89</code>" and "<code>CFLAGS=+O3 $(XCFLAGS)</code>" -works, contradicting the information in the next paragraph, but this may be -dependent on the specific compiler version.</li> - -<li>In either HPUX version, you need to set -"<code>CC=cc -Aa</code>" (or use <code>-Ae</code> if you -prefer), and set -"<code>CFLAGS=-D_HPUX_SOURCE -O $(XCFLAGS)</code>". Higher -levels of optimization than <code>-O</code> may work depending on your -compiler revision; some users have reported success with -<code>+O3</code>, some have not.</li> - -<li>Some users have reported needing <code>-DNOSYSTIME</code> and -<code>-D_POSIX_SOURCE</code> in <code>CFLAGS</code>, but recent tests -do not show these to be necessary.</li> - -<li>If you use gcc, it's a good idea to have a recent release -- at the -very least 2.7.2.1 or later.You may be able to get a working -executable with an older gcc by removing <code>-O</code> from -<code>CFLAGS</code>.</li> -</ul> - -<h4><a name="IBMAIX"></a>IBM AIX</h4> -<p> - We recommend installing gcc and GNU make, and using the Autoconf-based method.</p> -<p> -Other combinations are known to work, but are less well supported.</p> -<p> -Recent veresions of Ghostscript can trigger a 'TOC overflow' error with some compilers -on AIX. If this occurs, use the linker flag "-bbigtoc", which can either be added to -your configure options: -<p><code>configure LDFLAGS="-Wl,-bbigtoc"</code> -<p>Or on the make command line: -<p><code>make XLDFLAGS="-Wl,-bbigtoc"</code> -<h4> -<a NAME="Silicon_Graphics"></a>Silicon Graphics</h4> -<p> -(see Autoconf-based method above)</p> - -<p> -Users have had a lot of problems with the MIPSpro compilers on SGI systems. -We recommend using gcc. If you do choose to use the MIPSpro compiler, -please read the following carefully.</p> - -<ul> -<li> - To make the optimizer allocate enough table space, set - -<p><code>CFLAGS="-Olimit 2500"</code> (for older compilers) -<br><code>CFLAGS="-OPT:Olimit=2500"</code> (for newer compilers)</p> - -<p> -MIPSpro compiler version 3.19 is "older", and 7.1 is "newer"; we aren't -sure at what point in between the latter syntax was introduced.</p> -</li> -<li> -With the compiler shipped with Irix 5.2, use the <code>-ansi</code> - option.</li> - -<li> -The SGI C compiler may produce warnings about "Undefined the ANSI standard -library defined macro stdin/stdout/stderr". To suppress these warnings, add -"<code>-woff 608</code>" to the definition of <code>CFLAGS</code>.</li> - -<li> -The SGI C compiler shipped with Irix 6.1 and 6.2 will not compile -<code>zlib/deflate.c</code> properly with optimization. Compile this file -separately without <code>-O</code>.</li> - -<li> -With IRIX 6.5.x and the MIPSpro 7.x compilers there have been reports about -incorrect output and binaries that cause segmentation faults. Various -solutions have been suggested and you may want to try them in this order, -until you get a working binary:</li> - -<li> - <ul> - <li> - Compile <code>idict.c</code> and <code>isave.c</code> separately - without optimization after doing a normal compile; then relink.e.g.: - - <p> - <code>cc -OPT:Olimit=2500 -I. -I./obj -o ./obj/idict.o -c ./idict.c</code><br> - <code>cc -OPT:Olimit=2500 -I. -I./obj -o ./obj/isave.o -c ./isave.c</code></p> - </li> - <li> - Set <code>CFLAGS=</code> (no optimization).</li> - - <li> - Use only <code>-O2</code>. Compiler produces incorrect output - with <code>-O3</code> or "<code>-Ofast=ip32 -show</code>".</li> - - <li> - Irix 6.5.1m with MIPSpro compiler 7.2.1.1m, Irix 6.5.3m with MIPSpro - compiler 7.2.1, and probably other 6.5x / 7.2x combinations require - compiling with the <code>-o32</code> option. Compiling with the (default) - <code>-n32</code> option produces non-working executables. - <code>-O2</code> is OK (possibly except for <code>idict.c</code>), but - not <code>-O3</code>.</li> - </ul> -</li> -</ul> - -<h4><a name="Sun"></a>Oracle/Sun</h4> -<p> -see Autoconf-based method above)</p> - -<ul> -<li>The Sun unbundled C compiler (SC1.0) doesn't compile Ghostscript -properly with the <code>-fast</code> option: Ghostscript core-dumps in -<code>build_gs_font</code>. With that compiler use <code>-g</code>, -or use gcc instead.</li> - -<li>The Sun version of <code>dbx</code> often gives up with an error -message when trying to load Ghostscript. If this happens, use GNU -<code>gdb</code> instead. (<code>gdb</code> is more reliable than -<code>dbx</code> in other ways as well.)</li> - -<li>A bug in some versions of <code>zlib</code> results in an undefined -symbol <code>zmemcmp</code> when compiling with Sun cc. Use gcc -instead.</li> - -</ul> - -<h4><a name="Solaris"></a>Solaris</h4> - -<ul> -<li>Solaris 2.2 may require setting "<code>EXTRALIBS=-lsocket</code>". -Solaris 2.3 and later seem to require "<code>EXTRALIBS=-lnsl -lsocket -lposix4</code>".</li> - -<li>For Solaris 2.6 (and possibly some other versions), if you set -<code>SHARE_LIBPNG=1</code>, <code>SHARE_ZLIB=1</code>, or -<code>SHARE_JPEG=1</code>, you may need to set - -<p> - <code>XLDFLAGS=-R /usr/local/</code>xxx<code>/lib:/usr/local/lib</code></p> - -<p> -using the full path names of the relevant directories.</p> -</li> - -<li>Solaris 2.<em>n</em> uses <code>/usr/openwin/share/include</code> -for the X11 libraries rather than <code>/usr/local/X/include</code>.</li> - -<li>Solaris 2.<em>n</em> typically has Type 1 fonts in -<code>/usr/openwin/lib/X11/fonts/Type1/outline</code>.</li> - -<li>For Solaris 2.<code>n</code> in the makefile you must change -the definition of <code>INSTALL</code> from "<code>install -c</code>" to -"<code>/usr/ucb/install -c</code>".</li> - -<li>You may need to set <code>XLIBDIR</code> to the directory that holds -the X11 libraries, as for other SVR4 systems. Set <code>-DSVR4</code> -in <code>CFLAGS</code>.</li> - -<li>If you are using the SunPRO C compiler, don't use optimization level -<code>-xO3</code>. On SPARC platforms the compiler hangs; on Intel -platforms the generated code is incorrect. With this compiler on Intel, do -not use the <code>-native</code> flag: floating point computations -become unacceptably inaccurate. You can use <code>-xcg92</code> (SPARC -V8) and <code>-dalign</code> for better performance.</li> - -<li>One user reported compiling from source on a Linux NFS mounted -volume failed. Compiling from a local volume was the workaround.</li> - -</ul> - -<hr> -<h2><a name="Other_environments"></a>Other environments</h2> - -<h3><a name="No_multi_thread"></a>Environments lacking multi-threading</h3> - -<p> -All environments mentioned here by name have multi-threading capability. -However, if your environment doesn't, you can remove all need for -multi-threading by setting <code>SYNC=nosync</code> in the top-level -makefile. Note that you will not be able to use any so-called "async" -drivers (drivers that overlap interpretation and rasterization) if you do -this. No such drivers are in the <code>DEVICE_DEVS*</code> lists of any -makefile that we distribute.</p> - -<h3><a name="Plan_9"></a>Plan 9</h3> - -<p> -Use <code>unix-gcc.mak</code>, editing it to define</p> - -<blockquote><code> -CC=cc -GCFLAGS=-D_BSD_EXTENSION -DPlan9 -</code></blockquote> - -<p> -You will also probably have to edit many path names.</p> - -<hr> -<h2><a name="UFST_build"></a>How to build Ghostscript with UFST</h2> - -<p> -<em>Note: This section is only for customers who have a Monotype Imaging UFST license. -Other users please skip this section.</em></p> - - -<p> -Ghostscript sources do not include UFST sources. You need to obtain them separately. -The Ghostscript distributed source include only some source modules that provide a -bridge to UFST. You will also need an additional, UFST specific makefile: contact -Ghostscript support for more information</p> -<p> -If optioned in, the Ghostscript build system will build the UFST as part of the normal -bulid process (previously, the UFST was required to be built separately).</p> -<p> -To build Ghostscript with UFST, specify additional options for "make":</p> - -<dl> - <dt><code>UFST_BRIDGE=1</code></dt> - <dd>forces the UFST bridge to build.</dd> - - <dt><code>UFST_ROOT=path</code></dt> - <dd>specifies the path to UFST root directory or folder.</dd> - - <dt><code>UFST_CFLAGS=options</code></dt> - <dd>specifies C compiler options for UFST library. Refer to UFST manual for information about them.</dd> - - <dt><code>UFST_LIB_EXT=extension</code></dt> - <dd>sets the file name extension for object libraries. You must use the appropriate one for your platform and linker.</dd> -</dl> - - <p>An example for Unix/GCC :</p> -<blockquote> -<tt>UFST_BRIDGE=1 UFST_ROOT=../ufst UFST_CFLAGS=-DGCCx86 UFST_LIB_EXT=.a</tt> -</blockquote> - -<p>Starting with Ghostscript 9.x (Summer 2010), the above options are conveniently -inserted in the <code>Makefile</code> with -(this also automatically disable the freetype bridge):</p> -<blockquote> -<code>./configure --with-ufst=../ufst</code> -</blockquote> - -<p>For Windows/MSVC you need only specify UFST_ROOT. -msvc.mak sets the other options automatically.</p> - - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/News.htm b/doc/News.htm index 43de3817..d1268184 100644 --- a/doc/News.htm +++ b/doc/News.htm @@ -1,67 +1,26 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Recent Changes in Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> <!--START EDITING HERE--> <h1>Recent Changes in Ghostscript</h1> -<p> -This document is news about the most recent Ghostscript release. For -earlier versions, see the history documents: - -<blockquote> -<a href="History9.htm">History of Ghostscript versions 9.n</a><br> -</blockquote> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> <!-- [1.0 end visible header] ============================================== --> <!-- [2.0 begin contents] ================================================== --> -<h2><a name="Version9.56.0"></a>Version 9.56.1 (2022-04-04)</h2> +<h2><a name="Version10.00.0"></a>Version 10.00.0 (2022-09-21)</h2> <p> Highlights in this release include: <ul> <li> -<p><b>New PDF Interpreter:</b> This is an entirely new implementation written in C (rather than -PostScript, as before). For a full discussion of this change and reasons for it see: -<a href="https://ghostscript.com/pdfi.html">Changes Coming to the PDF Interpreter</a>. -<p>In this (9.56.0) release, the new PDF interpreter is now <em><u>ENABLED</u></em> by default -in Ghostscript, but the old PDF interpreter can be used as a fallback by specifying -<code>-dNEWPDF=false</code>. We've provided this so users that encounter issues with the new -interpreter can keep working while we iron out those issues, the option will not be available in -the long term. -<p>This also allows us to offer a new executable (<code>gpdf</code>, or <code>gpdfwin??.exe</code> -on Windows) which is <i>purely</i> for PDF input. For this release, those new binaries are not included -in the "install" make targets, nor in the Windows installers. -</li> -<li> -<p>Calling Ghostscript via the GS API is now thread safe. The one limitation is that the X11 devices for -Unix-like systems (x11, x11alpha, x11cmyk, x11cmyk2, x11cmyk4, x11cmyk8, x11gray2, x11gray4 and x11mono) -cannot be made thread safe, due to their interaction with the X11 server, those devices have been modified -to only allow one instance in an executable. +<p>The big change in this release is that the old PDF interpreter (written in PostScript) +is now fully deprecated. We will not be making any further changes to it. For this release, +the <code>-dNEWPDF=false</code> option remains for "emergency" use, but the option +to fall back to the old intepreter will also be removed in the next full release (10.01.0) in +spring 2023. +<p>So we once again encourage all users to test the new interpreter in their use cases, and +report any problems. </li> <li> -<p>The <code>PSD</code> output devices now write ICC profiles to their output files, for improved -color fidelity. +<p>The new PDF interpreter written in C has had several performance improvements. It was already +quicker for the majority of cases than the PostScript implementation, but we found further improvements +for common cases, and also several speed improvements in edge cases. </li> <li> <p>Our efforts in code hygiene and maintainability continue. @@ -93,7 +52,7 @@ for now, as we are aware that not everyone upgrades with every release.</h4> <p>(9.55.0) Changes to the <code>device API</code>. This will affect developers and maintainers of Ghostscript devices. Firstly, and most importantly, the way device-specific "procs" are specified has been rewritten to make it (we think!) clearer and less confusing. See -<a href="Drivers.htm">The Interface between Ghostscript and Device Drivers</a> and +<a href="https://ghostscript.readthedocs.io/Drivers.htm">The Interface between Ghostscript and Device Drivers</a> and <a href="https://www.notion.so/artifexsoftware/The-Great-Device-Rework-Of-2021-94092fe1395d4a088b91462f0ca5038a">The Great Device Rework Of 2021</a> for more details. </li> @@ -122,7 +81,7 @@ As we made "SAFER" the default mode, that became unacceptable, hence the new opt implementations. Firstly, as mentioned in the 9.50 release notes, SAFER now leaves standard PostScript functionality unchanged (except for the file access limitations). Secondly, the interaction with <code>save</code>/<code>restore</code> operations -has changed. See <a href="Use.htm#Safer">SAFER</a>. +has changed. See <a href="https://ghostscript.readthedocs.io/Use.htm#Safer">SAFER</a>. <p><strong>Important Note for Windows Users</strong>: <br> The file/path pattern matching is case-sensitive, even on Windows. This is a @@ -142,12 +101,12 @@ alternative solution or return the previous functionality, if there is genuinely option. </li> </ul> -<h3><a name="9.56.0_changelog"></a>Changelog</h3> +<h3><a name="10.00.0_changelog"></a>Changelog</h3> <p>From 9.55.0 onwards, in recognition of how unwieldy very large HTML files can become (History9.html had reached 8.1Mb!), we intend to only include the summary highlights (above). <p>For anyone wanting the full details of the changes in a release, we ask them to look at the history in our public git repository: -<a href="https://git.ghostscript.com/?p=ghostpdl.git;a=shortlog;h=refs/tags/ghostpdl-9.56.0">ghostpdl-9.56.0</a> log. +<a href="https://git.ghostscript.com/?p=ghostpdl.git;a=shortlog;h=refs/tags/ghostpdl-10.00.0">ghostpdl-10.00.0</a> log. <p>If this change does not draw negative feedback, History?.htm file(s) will be removed from the release archives. <!-- [2.0 end contents] ==================================================== --> @@ -170,16 +129,9 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. <p> -<small>Ghostscript version 9.56.1, 4 April 2022 +<small>Ghostscript version 10.00.0, 21 September 2022 <!-- [3.0 end visible trailer] ============================================= --> <!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Ps-style.htm b/doc/Ps-style.htm deleted file mode 100644 index 5cfcc5ef..00000000 --- a/doc/Ps-style.htm +++ /dev/null @@ -1,530 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript PostScript Coding Guidelines</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Ghostscript PostScript Coding Guidelines</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Summary">Summary of the coding guidelines</a></li> - <li><a href="#Introduction">Introduction</a></li> - <li><a href="#PS_features">Use of PostScript language features</a></li> - <li> - <ul> - <li><a href="#Restrictions">Restrictions</a></li> - <li><a href="#Protection">Protection</a></li> - <li><a href="#Standard_constructions">Standard constructions</a></li> - </ul> - </li> - <li><a href="#File_structuring">File structuring</a></li> - <li><a href="#Commenting">Commenting</a></li> - <li><a href="#Formatting">Formatting</a></li> - <li> - <ul> - <li><a href="#Indentation">Indentation</a></li> - <li><a href="#Spaces">Spaces</a></li> - </ul> - </li> - <li><a href="#Naming">Naming</a></li> - <li><a href="#Miscellany">Miscellany</a></li> - <li> - <ul> - <li><a href="#Non_standard_operators">Some useful non-standard operators</a></li> - <li><a href="#Useful_procedures">Some useful procedures</a></li> - <li><a href="#Other">Other</a></li> - </ul> - </li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p> -For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Summary"></a>Summary of the coding guidelines</h2> - -<ul> - -<li>Don't store into literals. - -<li>Use <code>loop</code> to create a block with multiple exits. - -<li>Use a dictionary or an array for multi-way switches. - -<li>Start every file with a copyright notice, the file name, and a one-line -summary. - -<li>Comment every procedure with the arguments and result, and with the -function of the procedure unless it's obvious. - -<li>Comment the stack contents ad lib, and particularly at the beginning of -every loop body. - -<li>Indent every 2 spaces. - -<li>Always put { at the end of a line, and } at the beginning of a line, -unless the contents are very short. - -<li>Always put spaces between adjacent tokens. - -<li>Use only lower-case letters and digits for names, or <a href="#Naming">Vienna style names</a>, -except for an initial "." for names only used within a single file. - -<li>Don't allocate objects in heavily used code. - -<li>Consider factoring out code into a procedure if it is used more than -once. - -</ul> - -<hr> - -<h2><a name="Introduction"></a>Introduction</h2> - -<p> -The many rules that Ghostscript's code follows almost everywhere are meant -to produce code that is easy to read. It's important to observe them as -much as possible in order to maintain a consistent style, but if you find a -rule getting in your way or producing ugly-looking results once in a while, -it's OK to break it. - -<hr> - -<h2><a name="PS_features"></a>Use of PostScript language features</h2> - -<h3><a name="Restrictions"></a>Restrictions</h3> - -<p> -If you need to store a value temporarily, don't write into a literal in the -code, as in this fragment to show a character given the character code: - -<blockquote><pre> -( ) dup 0 4 -1 roll put show -</pre></blockquote> - -<p> -Instead, allocate storage for it: - -<blockquote><pre> -1 string dup 0 4 -1 roll put show -</pre></blockquote> - -<h3><a name="Protection"></a>Protection</h3> - -<p> -If an object is never supposed to change, use <code>readonly</code> to -make it read-only. This applies especially to permanently allocated objects -such as constant strings or dictionaries. - -<p> -During initialization, and occasionally afterwards, it may be necessary to -store into a read-only dictionary, or to store a pointer to a dictionary in -local VM into a dictionary in global VM. The operators -<code>.forceput</code> and <code>.forceundef</code> are available for -this purpose. To make these operators inaccessible to ordinary programs, -they are removed from <code>systemdict</code> at the end of -initialization: system code that uses them should always use -<code>bind</code> and <code>odef</code> (or -<code>executeonly</code>) to make uses of them inaccessible as well. - -<h3><a name="Standard_constructions"></a>Standard constructions</h3> - -<h4>Multi-way conditionals</h4> - -<p> -If you write a block of code with more than about 3 exit points, the usual -way to do it would be like this: - -<blockquote><pre> -{ - ... { - ...1 - } { - ... { - ...2 - } { - ... { - ...3 - } { - ...4 - } ifelse - } ifelse - } ifelse -} -</pre></blockquote> - -<p> -However, this causes the 4 logically somewhat parallel code blocks to be -indented differently, and as the indentation increases, it becomes harder to -see the structure visually. As an alternative, you can do it this way: - -<blockquote><pre> -{ % The loop doesn't actually loop: it just provides a common exit. - ... { - ...1 - exit - } if - ... { - ...2 - exit - } if - ... { - ...3 - exit - } if - ...4 - exit -} loop -</pre></blockquote> - -<p> -Don't forget the final exit, to prevent the loop from actually looping. - -<h4>Switches</h4> - -<p> -Use a dictionary or an array of procedures to implement a 'switch', rather -than a series of conditionals, if there are more than about 3 cases. For -example, rather than: - -<blockquote><pre> -dup /a eq { - pop ...a -} { - dup /b eq { - pop ...b - } { - dup /c eq { - pop ...c - } { - ...x - } ifelse - } ifelse -} ifelse -</pre></blockquote> - -<p> -(or using the loop/exit construct suggested above), consider: - -<blockquote><pre> -/xyzdict mark - /a {...a} bind - /b {...b} bind - /c {...c} bind -.dicttomark readonly def -... -//xyzdict 1 index .knownget { - exch pop exec -} { - ...x -} ifelse -</pre></blockquote> - -<hr> - -<h2><a name="File_structuring"></a>File structuring</h2> - -<p> -Every code file should start with comments containing - -<ol> -<li>a copyright notice; -<li>the name of the file in the form of an RCS Id: - -<blockquote><pre> -% $Id: filename.ps $ -</pre></blockquote> - -<li>a very brief summary (preferably only one line) of what the file -contains. -</ol> - -<p> -If you create a file by copying the beginning of another file, be sure to -update the copyright year and change the file name. - -<hr> - -<h2><a name="Commenting"></a>Commenting</h2> - -<p> -If a file has well-defined functional sections, put a comment at the -beginning of each section to describe its purpose or function. - -<p> -Put a comment before every procedure to describe what the procedure does, -unless it's obvious or the procedure's function is defined by the PLRM. In -case of doubt, don't assume it's obvious. If the procedure may execute a -deliberate 'stop' or 'exit' not enclosed in 'stopped' or a loop -respectively, that should be mentioned. However, information about the -arguments and results should go in the argument and result comment -(described just below) if possible, not the functional comment. - -<p> -Put a comment on every procedure to describe the arguments and results: - -<blockquote><pre> -/hypot { % <num1> <num2> hypot <real> - dup mul exch dup mul add sqrt -} def -</pre></blockquote> - -<p> -There is another commenting style that some people prefer to the above: - -<blockquote><pre> -/hypot { % num1 num2 --> realnum - dup mul exch dup mul add sqrt -} def -</pre></blockquote> - -<p> -We have adopted the first style for consistency with Adobe's documentation, -but we recognize that there are technical arguments for and against both -styles, and might consider switching some time in the future. If you have -strong feelings either way, please make your opinion known to -<code>gs-devel@ghostscript.com</code>. - -<p> -Put comments describing the stack contents wherever you think they will be -helpful; put such a comment at the beginning of every loop body unless you -have a good reason not to. - -<p> -When you change a piece of code, do <em>not</em> include a comment with your -name or initials. Also, do <em>not</em> retain the old code in a comment, -unless you consider it essential to explain something about the new code; in -that case, retain as little as possible. (CVS logs do both of these things -better than manual editing.) However, if you make major changes in a -procedure or a file, you may put your initials, the date, and a brief -comment at the head of the procedure or file respectively. - -<hr> - -<h2><a name="Formatting"></a>Formatting</h2> - -<h3><a name="Indentation"></a>Indentation</h3> - -<p> -Indent 2 spaces per indentation level. You may use tabs at the left margin -for indentation, with 1 tab = 8 spaces, but you should not use tabs anywhere -else, except to place comments. - -<p> -Indent { } constructs like this: - -<blockquote><pre> -... { - ... -} { - ... -} ... -</pre></blockquote> - -<p> -If the body of a conditional or loop is no more than about 20 characters, -you can put the entire construct on a single line if you want: - -<blockquote><pre> -... { ... } if -</pre></blockquote> - -rather than - -<blockquote><pre> -... { - ... -} if -</pre></blockquote> - -<p> -There is another indentation style that many people prefer to the above: - -<blockquote><pre> -... -{ ... -} -{ ... -} ... -</pre></blockquote> - -<p> -We have adopted the first style for consistency with our C code, but we -recognize that there are technical arguments for and against both styles, -and might consider switching some time in the future. If you have strong -feelings either way, please make your opinion known to -<code>gs-devel@ghostscript.com</code>. - -<h3><a name="Spaces"></a>Spaces</h3> - -<p> -Always put spaces between two adjacent tokens, even if this isn't strictly -required. E.g., - -<blockquote><pre> -/Halftone /Category findresource -</pre></blockquote> - -<p> -not - -<blockquote><pre> -/Halftone/Category findresource -</pre></blockquote> - -<hr> - -<h2><a name="Naming"></a>Naming</h2> - -<p> -All names should consist only of letters and digits, possibly with an -initial ".", except for names drawn from the PostScript or PDF reference -manual, which must be capitalized as in the manual. In general, an initial -"." should be used for those and only those names that are not defined in a -private dictionary but that are meant to be used only in the file where they -are defined. - -<p> -For edits to existing code, names made up of multiple words should not use -any punctuation, or capitalization, to separate the words, again except for -names that must match a specification. For new code, you may use this -convention, or you may use the "Vienna" convention of capitalizing the first -letter of words, e.g., <code>readSubrs</code> rather than -<code>readsubrs</code>. If you use the Vienna convention, function names -should start with an upper case letter, variable names with a lower case -letter. Using the first letter of a variable name to indicate the -variable's type is optional, but if you do it, you should follow existing -codified usage (****** WE NEED A REFERENCE FOR THIS ******). - -<hr> - -<h2><a name="Miscellany"></a>Miscellany</h2> - -<h3><a name="Non_standard_operators"></a>Some useful non-standard -operators</h3> - -<dl> - -<dt><code><obj1> <obj2> ... <objn> <n> .execn ...</code> -<dd>This executes <code>obj1</code> through <code>objn</code> in that -order, essentially equivalent to - -<blockquote><pre> -<obj1> <obj2> ... <objn> <n> array astore {exec} forall -</pre></blockquote> - -<p> -except that it doesn't actually create the array. - -<dt><code><dict> <key> <b>.knownget</b> <value> true</code> -<dt><code><dict> <key> <b>.knownget</b> false</code> - -<dd>This combines <code>known</code> and <code>get</code> in the -obvious way. - -<dt><code><name> <proc> odef -</code> - -<dd>This defines <code>name</code> as a "pseudo-operator". The value of -<code>name</code> will be executable, will have type -<code>operatortype</code>, and will be executed if it appears directly in -the body of a procedure (like an operator, unlike a procedure), but what -will actually be executed will be <code>proc</code>. In addition, if the -execution of <code>proc</code> is ended prematurely (by -<code>stop</code>, including the <code>stop</code> that is normally -executed when an error occurs, or <code>exit</code>) and the operand and -dictionary stacks are at least as deep as they were when the "operator" was -invoked, the stacks will be cut back to their original depths before the -error is processed. Thus, if pseudo-operator procedures are careful not to -remove any of their operands until they reach a point in execution beyond -which they cannot possibly cause an error, they will behave just like -operators in that the stacks will appear to be unchanged if an error occurs. - -</dl> - -<h3><a name="Useful_procedures"></a>Some useful procedures</h3> - -<dl> - -<dt><code><object> <errorname> signalerror -</code> - -<dd>Signal an error with the given name and the given "current object". -This does exactly what the interpreter does when an error occurs. - -</dl> - -<h3><a name="Other"></a>Other</h3> - -<p> -If you can avoid it, don't allocate objects (strings, arrays, dictionaries, -gstates, etc.) in commonly used operators or procedures: these will need to -be garbage collected later, slowing down execution. Instead, keep values on -the stack, if you can. The <code>.execn</code> operator discussed above -may be helpful in doing this. - -<p> -If you find yourself writing the same stretch of code (more than about half -a dozen tokens) more than once, ask yourself whether it performs a function -that could be made into a procedure. - - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Ps2epsi.htm b/doc/Ps2epsi.htm deleted file mode 100644 index b3a85b03..00000000 --- a/doc/Ps2epsi.htm +++ /dev/null @@ -1,204 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Convert PostScript to Encapsulated PostScript Interchange Format</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Convert PostScript to Encapsulated PostScript Interchange Format</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Overview">Overview</a> - <li><a href="#Framemaker">Framemaker can use EPSI</a> - <li><a href="#Usage">Usage</a> - <li> - <ul> - <li><a href="#MSDOS_usage">MS-DOS</a> - <li><a href="#Unix_usage">Unix</a> - </ul> - </li> - <li><a href="#Limitations">Limitations</a> - <li><a href="#Files">Files</a> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p> -The information in this document was contributed by George Cameron -<<a href="mailto:george@bio-medical-physics.aberdeen.ac.uk">george@bio-medical-physics.aberdeen.ac.uk</a>>; -please direct to him any questions about it. Because the software -described here is no longer being maintained, this document may be -obsolete, or inconsistent with <code>ps2epsi.1</code>. - -<p> -For other information, see the <a href="Readme.htm">Ghostscript -overview</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Overview"></a>Overview</h2> - -<p> -<code>ps2epsi</code> is a utility based on Ghostscript, which takes as -input a PostScript file and generates as output a new file which conforms -to Adobe's Encapsulated PostScript Interchange (EPSI) format, a special -form of -<a href="http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf" -class="offsite">Encapsulated PostScript</a> -(EPS) which adds to the beginning of the file, as PostScript comments, a -low-resolution monochrome bitmap image of the final displayed page. -Programs which understand EPSI can use this bitmap as a preview on screen -of the full PostScript page. The displayed quality is often not very good, -but the final printed version uses the "real" PostScript, and thus has the -normal full PostScript quality. -<hr? -<h2><a name="Framemaker"></a>Framemaker can use EPSI</h2> - -<p> -The <a href="http://www.adobe.com/products/framemaker/main.html" -class="offsite">Adobe Framemaker</a> DTP system is one application which -understands EPSI files, and <code>ps2epsi</code> has been tested using -Framemaker 3.0 on a Sun workstation with a number of PostScript diagrams -from a variety of sources. Framemaker on other platforms may also be able -to use files made with <code>ps2epsi</code>, although this has not been -tested. - -<hr> - -<h2><a name="Usage"></a>Usage</h2> - -<h3><a name="MSDOS_usage"></a>MS-DOS</h3> - -<p> -Using the supplied batch file <code>ps2epsi.bat</code>, the command is - -<blockquote> -<code>ps2epsi</code> <b><em>infile.ps</em></b> <b><em>outfile.epi</em></b> -</blockquote> - -<p> -where <b><em>infile.ps</em></b> is the original PostScript file, and -<b><em>outfile.epi</em></b> is the output EPSI file to be created. - -<h3><a name="Unix_usage"></a>Unix</h3> - -<p> -Using the supplied shell script <code>ps2epsi</code>, the command is - -<blockquote> -<code>ps2epsi</code> <b><em>infile.ps</em></b> <b><em>[outfile.epsi]</em></b> -</blockquote> - -<p> -where <b><em>infile.ps</em></b> is the input file and -<b><em>outfile.epsi</em></b> is the output EPSI file to be created. If the -output filename is omitted, <code>ps2epsi</code> generates one from the -input filename; and any standard extension (<code>.ps</code>, -<code>.cps</code>, <code>.eps</code> or <code>.epsf</code>) of the -input file is replaced in the output file with the extension -<code>.epsi</code>. - -<hr> - -<h2><a name="Limitations"></a>Limitations</h2> - -<p> -Not all PostScript files can be encapsulated, because there are -restrictions in what is permitted in a PostScript file for it to be -properly encapsulated. <code>ps2epsi</code> does a little extra work to -try to help encapsulation, and it automatically calculates the bounding box -required for all encapsulated PostScript files, so most of the time it does -a pretty good job. There are certain to be cases, however, when -encapsulation fails because of the nature of the original PostScript file. - -<hr> - -<h2><a name="Files"></a>Files</h2> - -<blockquote><table> -<tr> - <th colspan="2">ps2epsi files</th> - </tr> -<tr> - <th align="left">File</th> - - <th align="left">Contents</th> - </tr> -<tr> - <td><code>ps2epsi.htm</code></td> - - <td>This document</td> - </tr> -<tr> - <td><code>ps2epsi.bat</code></td> - - <td>MS-DOS batch file</td> - </tr> -<tr> - <td><code>ps2epsi</code></td> - - <td>Unix shell script</td> - </tr> -<tr> - <td><code>ps2epsi.ps</code></td> - - <td>Ghostscript program which does the work</td> - </tr> -</table></blockquote> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> - -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Psfiles.htm b/doc/Psfiles.htm deleted file mode 100644 index b68435a7..00000000 --- a/doc/Psfiles.htm +++ /dev/null @@ -1,865 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>PostScript Files Distributed with Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - <div class="inner"> -<!--START EDITING HERE--> - -<h1>PostScript Files Distributed with Ghostscript</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#General">Generally used system files</a></li> - <li><a href="#Obscure">More obscure system files</a></li> - <li><a href="#Config">Configuration files</a></li> - <li><a href="#PDF_specific">PDF-specific system files</a></li> - <li><a href="#DPS_specific">Display PostScript-specific system files</a></li> - <li><a href="#Art">Art and examples</a></li> - <li><a href="#Utilities">Utilities</a></li> - <li><a href="#Development_tools">Development tools</a></li> - <li><a href="#Miscellany">Odds and ends</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="General"></a>Generally used system files</h2> - -<dl> -<dt><code>gs_*_e.ps</code></dt> -<dd> -These files define the Encodings known to Ghostscript. All of -them except <code>gs_std_e.ps</code> and <code>gs_il1_e.ps</code> -are loaded only if referred to. However some are additionally built into gscencs.c.</dd> - - -<dt> -PostScript Encodings:</dt> -<dd> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution.</dd> - -<dd> -<a href="../lib/gs_ce_e.ps"><code>gs_ce_e.ps</code></a> -</dd> - -<dd>These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</dd> - -<dd> -<a href="../Resource/Init/gs_il1_e.ps"><code>gs_il1_e.ps</code></a>, -<a href="../Resource/Init/gs_std_e.ps"><code>gs_std_e.ps</code></a>, -<a href="../Resource/Init/gs_sym_e.ps"><code>gs_sym_e.ps</code></a>. -</dd> - -<dt> -PDF Encodings:</dt> -<dd> -These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</dd> - -<dd> -<a href="../Resource/Init/gs_mex_e.ps"><code>gs_mex_e.ps</code></a>, -<a href="../Resource/Init/gs_mro_e.ps"><code>gs_mro_e.ps</code></a>, -<a href="../Resource/Init/gs_pdf_e.ps"><code>gs_pdf_e.ps</code></a>, -<a href="../Resource/Init/gs_wan_e.ps"><code>gs_wan_e.ps</code></a>. -</dd> - -<dt> -Non-standard Encodings:</dt> -<dd> -These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</dd> - -<dd> -<a href="../Resource/Init/gs_dbt_e.ps"><code>gs_dbt_e.ps</code></a>, -</dd> - -<dd> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution.</dd> - -<dd> -<a href="../lib/gs_il2_e.ps"><code>gs_il2_e.ps</code></a>, -<a href="../lib/gs_ksb_e.ps"><code>gs_ksb_e.ps</code></a>, -<a href="../lib/gs_lgo_e.ps"><code>gs_lgo_e.ps</code></a>, -<a href="../lib/gs_lgx_e.ps"><code>gs_lgx_e.ps</code></a>, -<a href="../lib/gs_wl1_e.ps"><code>gs_wl1_e.ps</code></a>, -<a href="../lib/gs_wl2_e.ps"><code>gs_wl2_e.ps</code></a>, -<a href="../lib/gs_wl5_e.ps"><code>gs_wl5_e.ps</code></a>. -</dd> - -<dt> -Pseudo-encodings:</dt> -<dd> -These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</dd> -<dd> -<a href="../Resource/Init/gs_mgl_e.ps"><code>gs_mgl_e.ps</code></a>. -</dd> - -<dd> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution.</dd> -<dd> -<a href="../lib/gs_lgo_e.ps"><code>gs_lgo_e.ps</code></a>, -<a href="../lib/gs_lgx_e.ps"><code>gs_lgx_e.ps</code></a>, -</dd> - -</dl> - - -<p>These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../Resource/Init/gs_btokn.ps"><code>gs_btokn.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads this in if the <code>btoken</code> -feature is included in the configuration. It provides support for binary -tokens.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cff.ps"><code>gs_cff.ps</code></a></dt> -<dd>Load CFF (compressed) fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_fntem.ps"><code>gs_fntem.ps</code></a></dt> -<dd>Code for emulating PostScript fonts with non-PostScript font technologies.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cidtt.ps"><code>gs_cidtt.ps</code></a></dt> -<dd>Code for emulating CID fonts with TrueType fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cidcm.ps"><code>gs_cidcm.ps</code></a></dt> -<dd>Code for recognizing font names of the form CIDFont-CMap (or -CIDFont--CMap) and creating the font automatically.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_ciddc.ps"><code>gs_ciddc.ps</code></a></dt> -<dd>Defines Decoding and CIDDecoding resource categories and related procsets. -Used for for emulating PostScript fonts with non-PostScript font technologies.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cidfm.ps"><code>gs_cidfm.ps</code></a></dt> -<dd>Provides resource mapping for CIDFont category.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cidfn.ps"><code>gs_cidfn.ps</code></a></dt> -<dd><code>ProcSet</code> for implementing <code>CIDFont</code> and -<code>CIDMap</code> resources.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cmap.ps"><code>gs_cmap.ps</code></a></dt> -<dd><code>ProcSet</code> for implementing <code>CMap</code> resources.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cspace.ps"><code>gs_cspace.ps</code></a></dt> -<dd> PostScript portion of the basic color space handling; -see the extensive comment at the head of the file -for information.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_dscp.ps"><code>gs_dscp.ps</code></a></dt> -<dd>Code to compensate for badly written PostScript files by setting -Orientation according to the DSC comments.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_epsf.ps"><code>gs_epsf.ps</code></a></dt> -<dd>Allow the interpreter to recognize DOS EPSF file headers, and skip to the -PostScript section of the file.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_fapi.ps"><code>gs_fapi.ps</code></a></dt> -<dd>Font API support.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_fonts.ps"><code>gs_fonts.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads this in. It initializes Ghostscript's -font machinery and provides some utility procedures that work with fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_frsd.ps"><code>gs_frsd.ps</code></a></dt> -<dd>Support for the PostScript LanguageLevel 3 -<code>ReusableStreamDecode</code> filter.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_img.ps"><code>gs_img.ps</code></a></dt> -<dd>Implementation of the traditional (non-dictionary) -form of the image and imagemask operators, and the -colorimage operator (including the Next alphaimage -facility).</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_init.ps"><code>gs_init.ps</code></a></dt> -<dd>Ghostscript reads this automatically when it starts up. It contains -definitions of many standard procedures and initialization for a wide -variety of things.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_lev2.ps"><code>gs_lev2.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads this in if the Ghostscript interpreter -includes Level 2 PostScript functions. It contains definitions of -procedures and miscellaneous initialization for the Level 2 functions.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_ll3.ps"><code>gs_ll3.ps</code></a></dt> -<dd>Initialize PostScript LanguageLevel 3 functions.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_resmp.ps"><code>gs_resmp.ps</code></a></dt> -<dd>A procset for redefining resource categories with a resource map.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_res.ps"><code>gs_res.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads this in if the Level 2 resource -machinery is included. Currently, this is the case for all Level 2 -configurations.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_setpd.ps"><code>gs_setpd.ps</code></a></dt> -<dd>Implementation of the <code>setpagedevice</code> operator.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_statd.ps"><code>gs_statd.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads this in. It creates a dummy -<code>statusdict</code> and some other environmental odds and ends for -the benefit of PostScript files that really want to be printed on a -LaserWriter.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_trap.ps"><code>gs_trap.ps</code></a></dt> -<dd>Stub support for the PostScript LanguageLevel 3 "In-RIP trapping" -feature.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_ttf.ps"><code>gs_ttf.ps</code></a></dt> -<dd>Support code for direct use of TrueType fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_typ32.ps"><code>gs_typ32.ps</code></a></dt> -<dd>Initialization file for Type 32 fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_typ42.ps"><code>gs_typ42.ps</code></a></dt> -<dd>Support code for Type 42 fonts (TrueType font in a PostScript "wrapper").</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_type1.ps"><code>gs_type1.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads this in if the Ghostscript interpreter -includes Type 1 font capability (which it normally does).</dd> -</dl> - -<hr> - -<h2><a name="Config"></a>Configuration files</h2> - -<p> -These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution. Users are allowed to modify them -to configure Ghostscript.</p> - -<dl> -<dt><a href="../Resource/Init/Fontmap"><code>Fontmap</code></a></dt> -<dd>Font mapping table.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/cidfmap"><code>cidfmap</code></a></dt> -<dd>CID font mapping table. Allows substitution of a CID font for another CID font or -a TrueType font for a CID font.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/FAPIconfig"><code>FAPIconfig</code></a></dt> -<dd>A configuration file for Font API client.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/FAPIfontmap"><code>FAPIfontmap</code></a></dt> -<dd>Font mapping table for Font-API-handled fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/FAPIcidfmap"><code>FAPIcidfmap</code></a></dt> -<dd>Font mapping table for Font-API-handled CID fonts.</dd> -</dl> - -<hr> - -<h2><a name="Obscure"></a>More obscure system files</h2> - -<p> -Unless otherwise stated, these files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../Resource/Init/gs_agl.ps"><code>gs_agl.ps</code></a></dt> -<dd>Contains the mapping from Adobe glyph names to Unicode values, used to -support TrueType fonts and disk-based Type 1 fonts.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_cet.ps"><code>gs_cet.ps</code></a></dt> -<dd>Sets a number of alternate defaults to make Ghostscript -behave more like Adobe CPSI. Useful for running the CET conformance -test suite.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_diskn.ps"><code>gs_diskn.ps</code></a></dt> -<dd>This file implements the <code>%disk</code> IODevice -(<code>diskn.dev</code> feature). See the the language documentation -for information on the use of the %disk# devices. These PostScript -modifications primarily perform the searching of all Searchable file -systems in a defined SearchOrder when a file reference does not contain -an explicit %device% specifier (such as <code>%os%</code> or -<code>%disk0</code>%). This is required to emulate undocumented -behaviour of Adobe PostScript printers that have a disk and was -experimentally determined.</dd> -</dl> - -<dl> -<dt><a href="../lib/gs_kanji.ps"><code>gs_kanji.ps</code></a></dt> -<dd>This file provides support for the Wadalab free Kanji font. It is not -included automatically in any configuration. This file is stored in the <code>lib</code> subdirectory.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_pdfwr.ps"><code>gs_pdfwr.ps</code></a></dt> -<dd>This file contains some patches for providing information to the -<code>pdfwrite</code> driver. It is included only if the -<code>pdfwrite</code> driver is included.</dd> -</dl> - -<dl> -<dt><a href="../lib/ht_ccsto.ps"><code>ht_ccsto.ps</code></a></dt> -<dd>A default stochastic CMYK halftone. This file is in the public domain. This file is stored in the <code>lib</code> subdirectory.</dd> -</dl> - -<dl> -<dt><a href="../lib/stcolor.ps"><code>stcolor.ps</code></a></dt> -<dd>Configure the (Epson) <code>stcolor</code> driver. This file is stored in the <code>lib</code> subdirectory.</dd> -</dl> - -<hr> - -<h2><a name="PDF_specific"></a>PDF-specific system files</h2> - -<p> -These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../Resource/Init/pdf_base.ps"><code>pdf_base.ps</code></a></dt> -<dd>Utilities for interpreting PDF objects and streams.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/pdf_draw.ps"><code>pdf_draw.ps</code></a></dt> -<dd>The interpreter for drawing-related PDF operations.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/pdf_font.ps"><code>pdf_font.ps</code></a></dt> -<dd>Code for handling fonts in PDF files.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/pdf_main.ps"><code>pdf_main.ps</code></a></dt> -<dd>Document- and page-level control for interpreting PDF files.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/pdf_ops.ps"><code>pdf_ops.ps</code></a></dt> -<dd>Definitions for most of the PDF operators.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/pdf_rbld.ps"><code>pdf_rbld.ps</code></a></dt> -<dd>Contains procedures for bebuilding damaged PDF files.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/pdf_sec.ps"><code>pdf_sec.ps</code></a></dt> -<dd>PDF security (encryption) code.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_icc.ps"><code>gs_icc.ps</code></a></dt> <dd>Support for -ICC color profiles. These are not a standard PostScript feature, but -are used in the PDF interpreter, as ICC profiles may be embedded in -PDF files.</dd> -</dl> - -<p> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution. These files are templates and should not be used -without modification.</p> - -<dl> -<dt><a href="../lib/PDFX_def.ps"><code>PDFX_def.ps</code></a></dt> -<dd>This is a sample prefix file for creating a PDF/X-3 document -with the <code>pdfwrite</code> device.</dd> -</dl> - -<dl> -<dt><a href="../lib/PDFA_def.ps"><code>PDFA_def.ps</code></a></dt> -<dd>This is a sample prefix file for creating a PDF/A document -with the <code>pdfwrite</code> device.</dd> -</dl> - -<hr> - -<h2><a name="DPS_specific"></a>Display PostScript-specific system files</h2> - -<p> -These files are found in the <code>Resource/Init</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../Resource/Init/gs_dpnxt.ps"><code>gs_dpnxt.ps</code></a></dt> -<dd>NeXT Display PostScript extensions.</dd> -</dl> - -<dl> -<dt><a href="../Resource/Init/gs_dps.ps"><code>gs_dps.ps</code></a>, -<a href="../Resource/Init/gs_dps1.ps"><code>gs_dps1.ps</code></a>, -<a href="../Resource/Init/gs_dps2.ps"><code>gs_dps2.ps</code></a></dt> -<dd><code>gs_init.ps</code> reads these in if the <code>dps</code> -feature is included in the configuration. They provide support for various -Display PostScript and Level 2 features.</dd> -</dl> - -<hr> - -<h2><a name="Art"></a>Art and examples</h2> - -<p> -These files are found in the <code>examples</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../examples/alphabet.ps"><code>alphabet.ps</code></a></dt> -<dd>Prints a sample alphabet at several different sizes.</dd> -</dl> - -<dl> -<dt><a href="../examples/annots.pdf"><code>annots.pdf</code></a></dt> -<dd>A sample file with a wide variety of PDF "annotations".</dd> -</dl> - -<dl> -<dt><a href="../examples/colorcir.ps"><code>colorcir.ps</code></a></dt> -<dd>A set of nested ellipses made up of colored bars.</dd> -</dl> - -<dl> -<dt><a href="../examples/doretree.ps"><code>doretree.ps</code></a></dt> -<dd>A 3-D image produced by a modeling program. This file is in the public -domain.</dd> -</dl> - -<dl> -<dt><a href="../examples/escher.ps"><code>escher.ps</code></a></dt> -<dd>A colored version of a hexagonally symmetric Escher drawing of -interlocking butterflies. Can be printed on monochrome devices, with -somewhat less dramatic results.</dd> -</dl> - -<dl> -<dt><a href="../examples/golfer.eps"><code>golfer.eps</code></a></dt> -<dd>A gray-scale picture of a stylishly dressed woman swinging a golf club.</dd> -</dl> - -<dl> -<dt><a href="../examples/grayalph.ps"><code>grayalph.ps</code></a></dt> -<dd>Grayscaled text test pattern.</dd> -</dl> - -<dl> -<dt><a href="../examples/ridt91.eps"><code>ridt91.eps</code></a></dt> -<dd>The RIDT '91 logo. Note that since this is an EPS file, you will have -to add "<code>-c showpage</code>" at the end of the command line to -print it or convert it to a raster file.</dd> -</dl> - -<dl> -<dt><a href="../examples/snowflak.ps"><code>snowflak.ps</code></a></dt> -<dd>A rectangular grid of intricate colored snowflakes. (May render very -slowly.)</dd> -</dl> - -<dl> -<dt><a href="../examples/text_graph_image_cmyk_rgb.pdf"><code>text_graph_image_cmyk_rgb.pdf</code></a></dt> -<dd>A simple PDF containing text and graphics in both RGB and CMYK spaces.</dd> -</dl> - -<dl> -<dt><a href="../examples/text_graphic_image.pdf"><code>text_graphic_image.pdf</code></a></dt> -<dd>A simple PDF containing text and graphics in RGB space.</dd> -</dl> - -<dl> -<dt><a href="../examples/tiger.eps"><code>tiger.eps</code></a></dt> -<dd>A dramatic colored picture of a tiger's head.</dd> -</dl> - -<dl> -<dt><a href="../examples/transparency_example.ps"><code>transparency_example.ps</code></a></dt> -<dd>A simple example of transparency.</dd> -</dl> - -<dl> -<dt><a href="../examples/vasarely.ps"><code>vasarely.ps</code></a></dt> -<dd>Colored rectangles and ellipses inspired by Victor Vasarely's experiments -with tilting circles and squares.</dd> -</dl> - -<dl> -<dt><a href="../examples/waterfal.ps"><code>waterfal.ps</code></a></dt> -<dd>Prints text in a variety of different sizes, to help evaluate the -quality of text rendering.</dd> -</dl> - -<hr> - -<h2><a name="Utilities"></a>Utilities</h2> - -<p> -For more information on these utility programs, see the comments at the -start of each file . The ones marked (*) have batch files or shell -scripts of the same name (like <code>bdftops</code> and -<code>bdftops.bat</code>) to invoke them conveniently.</p> - -<p> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../lib/align.ps"><code>align.ps</code></a></dt> -<dd>A test page for determining the proper margin and offset parameters for -your printer.</dd> -</dl> - -<dl> -<dt><a href="../lib/caption.ps"><code>caption.ps</code></a></dt> -<dd>A file for putting a caption in a box at the bottom of each page, -useful for trade show demos.</dd> -</dl> - -<dl> -<dt><a href="../lib/cat.ps"><code>cat.ps</code></a></dt> -<dd>Appends one file to another. Primarily used to overcome the -'copy' limitation of Windows command shell for ps2epsi</dd> -</dl> - -<dl> -<dt><a href="../lib/cid2code.ps"><code>cid2code.ps</code></a></dt> -<dd>A utility for creating maps from CIDs to Unicode, useful when -substituting a TrueType font for an Adobe font.</dd> -</dl> - -<dl> -<dt><a href="../lib/docie.ps"><code>docie.ps</code></a></dt> -<dd>An emulation of the CIE color mapping algorithms.</dd> -</dl> - -<dl> -<dt><a href="../lib/font2pcl.ps"><code>font2pcl.ps</code></a></dt> -<dd>A utility to write a font as a PCL bitmap font.</dd> -</dl> - -<dl> -<dt><a href="../lib/gslp.ps"><code>gslp.ps</code></a> *</dt> -<dd>A utility for doing "line printing" of plain text files.</dd> -</dl> - -<dl> -<dt><a href="../lib/gsnup.ps"><code>gsnup.ps</code></a></dt> -<dd>A file that you can concatenate in front of (very well-behaved) -PostScript files to do N-up printing. It is deliberately simple and naive: -for more generality, use <code>psnup</code> (which, however, requires DSC -comments).</dd> -</dl> - -<dl> -<dt><a href="../lib/jispaper.ps"><code>jispaper.ps</code></a></dt> -<dd>A file that makes the <code>b0</code> through <code>b6</code> -procedures refer to JIS B paper sizes rather than ISO B.</dd> -</dl> - - -<dl> -<dt><a href="../lib/landscap.ps"><code>landscap.ps</code></a></dt> -<dd>A file that you can put in front of your own files to get them rendered -in landscape mode.</dd> -</dl> - -<dl> -<dt><a href="../lib/mkcidfm.ps"><code>mkcidfm.ps</code></a></dt> -<dd>A utility for creating a CID font mapping table <code>cidfmap</code> -from fonts found in a specified directory.</dd> -</dl> - -<dl> -<dt><a href="../lib/pdf2dsc.ps"><code>pdf2dsc.ps</code></a></dt> -<dd>A utility to read a PDF file and produce a DSC "index" file.</dd> -</dl> - -<dl> -<dt><a href="../lib/pf2afm.ps"><code>pf2afm.ps</code></a> *</dt> -<dd>A utility for producing AFM files from PFA, PFB, and optionally PFM -files.</dd> -</dl> - -<dl> -<dt><a href="../lib/pfbtopfa.ps"><code>pfbtopfa.ps</code></a> *</dt> -<dd>A utility to convert PFB (binary) font files to PFA (text) format.</dd> -</dl> - -<dl> -<dt><a href="../lib/prfont.ps"><code>prfont.ps</code></a></dt> -<dd>A utility to print a font catalog.</dd> -</dl> - -<dl> -<dt><a href="../lib/printafm.ps"><code>printafm.ps</code></a></dt> -<dd>A utility to print an AFM file on standard output.</dd> -</dl> - -<dl> -<dt><a href="../lib/ps2ai.ps"><code>ps2ai.ps</code></a></dt> -<dd>A utility for converting an arbitrary PostScript file into a form -compatible with Adobe Illustrator. NOTE: <code>ps2ai</code> doesn't -work properly with Adobe's Helvetica-Oblique font, and other fonts whose -original <code>FontMatrix</code> involves skewing or rotation.</dd> -</dl> - -<dl> -<dt><a href="../lib/ps2epsi.ps"><code>ps2epsi.ps</code></a> *</dt> -<dd>A utility for converting an arbitrary PostScript file into EPSI form.</dd> -</dl> - -<dl> -<dt><a href="../lib/rollconv.ps"><code>rollconv.ps</code></a></dt> -<dd>A utility for converting files produced by Macromedia's -<code>Rollup</code> program to a Type 0 form directly usable by -Ghostscript.</dd> -</dl> - -<dl> -<dt><a href="../lib/stocht.ps"><code>stocht.ps</code></a></dt> -<dd>A file that installs the StochasticDefault halftone as the default, -which may improve output quality on inkjet printers. See the file for more -information.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewcmyk.ps"><code>viewcmyk.ps</code></a></dt> -<dd>A utility for displaying CMYK files.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewgif.ps"><code>viewgif.ps</code></a></dt> -<dd>A utility for displaying GIF files.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewjpeg.ps"><code>viewjpeg.ps</code></a></dt> -<dd>A utility for displaying JPEG files.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewmiff.ps"><code>viewmiff.ps</code></a></dt> -<dd>A utility for displaying MIFF files.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewpbm.ps"><code>viewpbm.ps</code></a></dt> -<dd>A utility for displaying PBM/PGM/PPM files.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewpcx.ps"><code>viewpcx.ps</code></a></dt> -<dd>A utility for displaying PCX files.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewrgb.ps"><code>viewrgb.ps</code></a></dt> -<dd>A utility for displaying files created by -sDEVICE=bitrgb.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewraw.ps"><code>viewraw.ps</code></a></dt> -<dd>An extended utility for displaying files created by -sDEVICE=bitrgb.</dd> -</dl> - -<hr> - -<h2><a name="Development_tools"></a>Development tools</h2> - -<p> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../lib/acctest.ps"><code>acctest.ps</code></a></dt> -<dd>A utility that checks whether the interpreter enforces access -restrictions.</dd> -</dl> - -<dl> -<dt><a href="../lib/image-qa.ps"><code>image-qa.ps</code></a></dt> -<dd>A comprehensive test of the image display operators.</dd> -</dl> - -<dl> -<dt><a href="../lib/ppath.ps"><code>ppath.ps</code></a></dt> -<dd>A couple of utilities for printing out the current path, for debugging.</dd> -</dl> - -<dl> -<dt><a href="../lib/pphs.ps"><code>pphs.ps</code></a></dt> -<dd>A utility to print the Primary Hint Stream of a linearized PDF file.</dd> -</dl> - -<dl> -<dt><a href="../lib/traceimg.ps"><code>traceimg.ps</code></a></dt> -<dd>Trace the data supplied to the <code>image</code> operator.</dd> -</dl> - -<dl> -<dt><a href="../lib/traceop.ps"><code>traceop.ps</code></a></dt> -<dd>A utility for tracing uses of any procedure or operator for debugging.</dd> -</dl> - -<dl> -<dt><a href="../lib/uninfo.ps"><code>uninfo.ps</code></a></dt> -<dd>Some utilities for printing out PostScript data structures.</dd> -</dl> - -<dl> -<dt><a href="../lib/viewps2a.ps"><code>viewps2a.ps</code></a></dt> -<dd>A utility for displaying the output of <code>ps2ascii.ps</code>.</dd> -</dl> - -<dl> -<dt><a href="../lib/winmaps.ps"><code>winmaps.ps</code></a></dt> -<dd>A utility for creating mappings between the Adobe encodings and the -Microsoft Windows character sets.</dd> -</dl> - -<dl> -<dt><a href="../lib/zeroline.ps"><code>zeroline.ps</code></a></dt> -<dd>A utility for testing how interpreters handle zero-width lines.</dd> -</dl> - -<hr> - -<h2><a name="Miscellany"></a>Odds and ends</h2> - -<p> -These files are found in the <code>lib</code> subdirectory of -the Ghostscript source distribution.</p> - -<dl> -<dt><a href="../lib/jobseparator.ps"><code>jobseparator.ps</code></a></dt> -<dd>Convience file containing a job separator sequence for use -when passing files with -dJOBSERVER.</dd> -</dl> - -<dl> -<dt><a href="../lib/lines.ps"><code>lines.ps</code></a></dt> -<dd>A test program for line joins and caps.</dd> -</dl> - -<dl> -<dt><a href="../lib/stcinfo.ps"><code>stcinfo.ps</code></a></dt> -<dd>Print and show parameters of the (Epson) <code>stcolor</code> driver.</dd> -</dl> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Readme.htm b/doc/Readme.htm deleted file mode 100644 index 781c6485..00000000 --- a/doc/Readme.htm +++ /dev/null @@ -1,560 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Overview of Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Introduction</h1> - -<p> -This document is a roadmap to the Ghostscript documentation. -After looking through it, if you want to install Ghostscript and not only -use it, we recommend you read <a href="Install.htm">how to install -Ghostscript</a>, and <a href="Make.htm">how to compile Ghostscript</a> from -source code (which is necessary before installing it on Unix and VMS - systems).</p> - -<!-- [1.3 end hint] ======================================================== --> - - - -<!-- [1.2 begin table of contents] ========================================= --> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="WhatIsGS.htm">What is Ghostscript?</a></li> - <li> - <ul> - <li><a href="WhatIsGS.htm#GhostPDF">What is GhostPDF?</a></li> - <li><a href="WhatIsGS.htm#GhostPCL">What is GhostPCL?</a></li> - <li><a href="WhatIsGS.htm#GhostXPS">What is GhostXPS?</a></li> - <li><a href="WhatIsGS.htm#GhostSVG">What is GhostSVG?</a></li> - <li><a href="WhatIsGS.htm#GhostPDL">What is GhostPDL?</a></li> - </ul> - </li> - <li><a href="#Theme_roadmap">Document roadmap by theme</a></li> - <li> - <ul> - <li><a href="#New_users">What should I read if I'm a new user?</a></li> - <li><a href="#Two_Ghostscripts">GPL Ghostscript and commercial Ghostscript</a></li> - <li><a href="#Before_building">Before building Ghostscript</a></li> - <li><a href="#Not_a_new_user">What should I read if I'm not a new user?</a></li> - <li><a href="#Developer">What if I'm a developer?</a></li> - <li><a href="#Writer">What if I'm writing documentation?</a></li> - </ul> - </li> - - <li><a href="#Web_presence">Presence on the World Wide Web</a></li> - <li> - <ul> - <li><a href="#Web_home_page">Ghostscript's home pages</a></li> - <li><a href="#Adobe_documentation">Adobe PostScript, Encapsulated - PostScript, and PDF reference documentation</a></li> - <li><a href="#Web_other">Other material on the WWW</a></li> - </ul> - </li> - - <li><a href="#Ordered_roadmap">Which document contains what?</a></li> - <li> - <ul> - <li>Primarily for users:</li> - <li> - <table> - <tr colspan="3"> - <td width="33%"> - <a href="Deprecated.htm">Deprecated.htm</a><br> - <a href="Devices.htm">Devices.htm</a><br> - <a href="Ps2epsi.htm">Ps2epsi.htm</a></td> - <td width="33%"> - <a href="VectorDevices.htm">VectorDevices.htm</a><br> - <a href="#Readme">Readme.htm</a></td> - <td width="33%"> - <a href="Unix-lpr.htm">Unix-lpr.htm</a><br> - <a href="Use.htm">Use.htm</a></td></tr> - </table> - </li> - <li> - <li>For both users and developers:</li> - <li> - <table> - <tr colspan="3"> - <td width="33%"> - <a href="Fonts.htm">Fonts.htm</a><br> - <a href="History9.htm">History*.htm</a><br> - <a href="Install.htm">Install.htm</a><br></td> - <td width="33%"> - <a href="Language.htm">Language.htm</a><br> - <a href="Make.htm">Make.htm</a><br> - <a href="News.htm">News.htm</a></td> - <td width="33%"> - <a href="Psfiles.htm">Psfiles.htm</a><br> - <a href="#COPYING">COPYING</a><br> - <a href="thirdparty.htm">thirdparty.htm</a></td></tr> - </table> - </li> - <li> - <li>Primarily for developers:</li> - </li> - <li> - <table> - <tr colspan="3"> - <td width="33%"> - <a href="API.htm">API.htm</a><br> - <a href="C-style.htm">C-style.htm</a><br> - <a href="DLL.htm">DLL.htm</a><br> - <a href="Internal.htm">Internal.htm</a><br></td> - <td> - <a href="Lib.htm">Lib.htm</a><br> - <a href="Develop.htm">Develop.htm</a><br> - <a href="Drivers.htm">Drivers.htm</a></td> - <td> - <a href="Ps-style.htm">Ps-style.htm</a><br> - <a href="Release.htm">Release.htm</a><br> - <a href="Source.htm">Source.htm</a><br></td></tr> - </table> - </li> - </ul> - </li> -</ul> -<br> -<!-- [1.2 end table of contents] =========================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Theme_roadmap"></a>Document roadmap by theme</h2> - -<h3><a name="New_users"></a>What should I read if I'm a new user?</h3> - -<ul> - - <li>how to <a href="Use.htm">use Ghostscript</a>. This includes both - a quickstart introduction to the commandline version and more extensive - reference material.</li> - - <li>detailed information about <a href="Devices.htm">specific - devices</a> that Ghostscript can use for output</li> - - <li>more detailed information about how to use Ghostscript under - Unix with <code>lpr</code> <a href="Unix-lpr.htm">as a filter</a> - for printing</li> - - <li>for information about known problems or to report a new one, - please visit <a href="http://bugs.ghostscript.com/">bugs.ghostscript.com</a> - but remember that free versions of Ghostscript come with with - <strong>NO WARRANTY</strong> and <strong>NO SUPPORT</strong></li> -</ul> - -<h3><a name="Two_Ghostscripts"></a>GPL and commercial Ghostscript</h3> -<p> -GPL Ghostscript, Artifex Ghostscript and AFPL Ghostscript are different releases.</p> - -<ul> - <li>additional information about <a href="COPYING">GPL Ghostscript - releases</a> that is not relevant to commercial versions.</li> -</ul> - -<p> -If you run into any questions, or if you are going to be using Ghostscript - extensively, you should at least skim, and probably eventually read:</p> - -<ul> - <li> about the <a href="Fonts.htm">fonts distributed with - Ghostscript</a>, including how to add or replace fonts</li> - - <li> a description of <a href="Language.htm">the Ghostscript language</a>, - and its differences from the documented PostScript language</li> - - <li> about the <a href="Psfiles.htm">postscript files distributed with - Ghostscript</a> (other than fonts)</li> -</ul> - -<h3><a name="Before_building"></a>Before building Ghostscript</h3> - -<p> -If you are going to compile Ghostscript from source, rather than just use an executable - you got from somewhere, you may want to read:</p> - -<ul> - <li> <a href="Make.htm">how to build Ghostscript</a> and - <a href="Install.htm">install it</a></li> -</ul> - -<hr> - -<h2><a name="Not_a_new_user"></a>What should I read if I'm not a new user?</h2> - -<p> -If you have already used Ghostscript, when you receive a new release you - should begin by reading this file, then:</p> - -<ul> - <li> <a href="News.htm">News</a>, for incompatible changes and new - features in the current release;</li> - - <li> if you wish, History#.htm (currently <a - href="History9.htm">History9.htm</a>), for changes in the current and earlier releases.</li> -</ul> - -<hr> - -<h2><a name="Developer"></a>What if I'm a developer?</h2> - -<p> -If you are going to do any development on or with Ghostscript at all, you -should at least look at:</p> - -<ul> - <li>the <a href="Develop.htm">roadmap documentation</a> for Ghostscript's - source files and architecture</li> -</ul> - -<p> - If you are going to write a new driver for Ghostscript, you should read:</p> - -<ul> - <li> the <a href="Source.htm">guide to the Ghostscript source code</a></li> - - <li> the interface between Ghostscript and <a href="Drivers.htm">device - drivers</a></li> -</ul> - -<p> -If you are considering distributing GPL Ghostscript in conjunction -with a commercial product, you should read the - <a href="COPYING">license</a> carefully, and you should also read</p> - -<ul> - <li> additional clarification of the circumstances under which Ghostscript - can be distributed with a commercial product</li> -</ul> - -<p> -If you intend to use Ghostscript in the form of a dynamic link library -(DLL) under OS/2 or Microsoft Windows or in the form of shared object -under Linux, read</p> - -<ul> - <li> documentation on <a href="API.htm">Ghostscript Interpreter API</a></li> -</ul> - -<p> -If you want to use Ghostscript as part of another program--as a callable -PostScript language interpreter--and not as a DLL or as a self-contained -executable application, you should begin by reading:</p> - -<ul> - <li> the source file <code>imain.h</code>, the documented - API for Ghostscript <em>not</em> as a DLL</li> -</ul> - -<p> -or if you are going to use only the Ghostscript graphics library:</p> - -<ul> - <li> about the structure of the <a href="Lib.htm">Ghostscript library</a> - and its interfaces</li> - -</ul> - -<hr> - -<h2><a name="Writer"></a>What if I'm writing documentation?</h2> - -<p> -If you are editing or adding to Ghostscript's existing documentation in - HTML format, or writing a new document, you should contact us on our - IRC channel or the <code>gs-devel</code> mailing list for guidance, - links to those are on: <a href="https://www.ghostscript.com">www.ghostscript.com</a>. -</p> - -<hr> - -<h2><a name="Web_presence"></a>Presence on the World Wide Web</h2> - -<h3><a name="Web_home_page"></a>Ghostscript's home page</h3> - -<p> -Ghostscript has a home page on the World Wide Web with helpful information -such as the FAQ (Frequently Asked Questions):</p> - -<blockquote> -<a href="http://www.ghostscript.com/" class="offsite">http://www.ghostscript.com/</a> -</blockquote> - -<h3><a name="Adobe_documentation"></a>Adobe PostScript, Encapsulated -PostScript, and PDF reference documentation</h3> - -<p> -Adobe makes a wealth of technical documentation available over the Web, - including the -<a href="http://partners.adobe.com/public/developer/en/ps/PLRM.pdf" -class="offsite"> -PostScript Language Reference Manual (Third Edition)</a>; the -<a href="http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf" -class="offsite"> -Encapsulated PostScript</a> (EPS) Format Specification version 3, including -<a href="#Ps2epsi">Encapsulated PostScript Interchange (EPSI)</a> - format; the -<a href="http://partners.adobe.com/public/developer/pdf/index_reference.html" -class="offsite">PDF Reference manuals</a>. -The <a href="http://partners.adobe.com/public/developer/acrobat/sdk/index.html" -class="offsite">Acrobat SDK</a> contains -<a href="http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html" class="offset"> -pdfmark and Acrobat Distiller parameters</a> documentation. -Some of these documents -are also available at <a href="ftp://ftp.adobe.com/pub/adobe/" -class="offsite">Adobe's ftp - site</a>, but not necessarily under the same filenames.</p> - -<h3><a name="Web_other"></a>Other material on the WWW</h3> - -<p> -Much other material about Ghostscript is available on the World Wide Web, -both as web pages and as archived Usenet and mailing list discussions. Use - the well-known search engines to find such material.</p> - -<hr> - -<h2><a name="Ordered_roadmap"></a>Which document contains what?</h2> - -<p> Here is the list in alphabetic order of Ghostscript documentation, -with explanations of the contents.</p> - -<dl> -<dt><a name="API"></a><a href="API.htm"><b>API.htm</b></a> -<dd>On MS-Windows and OS/2, Ghostscript is compiled as a dynamic -link library (DLL). On Linux, Ghostscript can be compiled as -a shared object. This describes how to use it. For developers.</dd></dt> -</dl> - -<dl> -<dt><a name="C-style"></a><a href="C-style.htm"><b>C-style.htm</b></a> -<dd> Guidelines and style for C coding, which you should follow -if, for example, you <a href="#Drivers">write a new driver</a> or add or -change something in Ghostscript. For developers.</dd></dt> -</dl> - -<dl> -<dt><a name="DLL"></a><a href="DLL.htm"><b>DLL.htm</b></a> -<dd> On OS/2, MS Windows-16 and MS Windows-32 platforms, Ghostscript is -compiled as a dynamic link library (DLL). This describes how to use it. -For developers. <b>This DLL interface is obsolete.</b> -Use <a href="#API"><b>API.htm</b></a> instead.</dd></dt> -</dl> - -<dl> -<dt><a name="Develop"></a><a href="Develop.htm"><b>Develop.htm</b></a> -<dd> Code orientation for developers. Contains a detailed breakdown of -the source files by functional group, and overviews of the major -architectural features and services.</dd></dt> -</dl> - -<dl> -<dt><a name="Deprecated"></a><a href="Deprecated.htm"><b>Deprecated.htm</b></a></dt> -<dd> Documention for deprecated devices and features. Features described here -will be removed in future versions of Ghostscript.</dd> -</dl> - -<dl> -<dt><a name="Devices"></a><a href="Devices.htm"><b>Devices.htm</b></a> -<dd> Detailed information about some specific devices for which Ghostscript -can produce output. Run "<code>gs -h</code>" to see which -devices a particular version of Ghostscript is built to use.</dd></dt> -</dl> - -<dl> -<dt><a name="Drivers"></a><a href="Drivers.htm"><b>Drivers.htm</b></a> -<dd> Describes the interface between Ghostscript and device drivers. If -you do this, you should also read and use the <a href="#C-style">C style -and coding guidelines</a>. Necessary to develop a new driver. For -developers.</dd></dt> -</dl> - -<dl> -<dt><a name="Fonts"></a><a href="Fonts.htm"><b>Fonts.htm</b></a> <dd> All -about fonts freely available for Ghostscript, and how to add and use new -fonts. Also describes how to use Ghostscript fonts as X Windows fonts. For -both users and developers.</dd></dt> -</dl> - -<dl> -<dt><a name="History"></a><b>History*.htm</b> -<dd> The history of changes in all Ghostscript releases: -<blockquote> -<a href="History9.htm">History9.htm</a> for Ghostscript versions 9.n<br> -</blockquote></dd></dt> -</dl> - -<dl> -<dt><a name="Install"></a><a href="Install.htm"><b>Install.htm</b></a> -<dd> How to install Ghostscript. See also <a href="#Make">how to build -it</a>.</dd></dt> -</dl> - -<dl> -<dt><a name="Internal"></a><a href="Internal.htm"><b>Internal.htm</b></a> -<dd> Description of operators that are for internal/developer use only.</dd></dt> -</dl> - -<dl> -<dt><a name="Language"></a><a href="Language.htm"><b>Language.htm</b></a> -<dd> The relationship between the Ghostscript interpreter and the -PostScript language as defined by Adobe.</dd></dt> -</dl> - -<dl> -<dt><a name="Lib"></a><a href="Lib.htm"><b>Lib.htm</b></a> -<dd> A description of the Ghostscript library, a set of procedures to -implement the graphics and filtering capabilities that are primitive -operations in the PostScript language and in Adobe Portable Document Format -(PDF). For developers.</dd></dt> -</dl> - -<dl> -<dt><a name="Make"></a><a href="Make.htm"><b>Make.htm</b></a> -<dd> How to build Ghostscript executables from the source code. See also -<a href="#Install">how to install it</a>. It's not necessary to be a highly -experienced developer to build or install Ghostscript, but some experience -is needed.</dd></dt> -</dl> - -<dl> -<dt><a name="News"></a><a href="News.htm"><b>News.htm</b></a> -<dd> A brief description of the latest release or pre-release of -Ghostscript, and a list of any incompatible changes in it. Changes in older -releases are described in the history files "<code>History*.htm</code>", -which are usually installed in the documentation directory. Run -"<code>gs -h</code>" to see where that is.</dd></dt> -</dl> - -<dl> -<dt><a name="Ps-style"></a><a -href="Ps-style.htm"><b>Ps-style.htm</b></a> -<dd> The guidelines and style for postscript coding in Ghostscript. Some -of Ghostscript is implemented in the postscript language itself, and -various utilities and examples are distributed with it. You should -follow these guidelines if you're extending or modifying those files. -For developers.</dd></dt> -</dl> - -<dl> -<dt><a name="Ps2epsi"></a><a href="Ps2epsi.htm"><b>Ps2epsi.htm</b></a> -<dd> Detailed information on how to use Ghostscript through -<code>ps2epsi</code> to convert PostScript to Adobe -Encapsulated PostScript Interchange (EPSI) format.</dd></dt> -</dl> - -<dl> -<dt><a name="Vector"></a><a href="VectorDevices.htm"><b>VectorDevices.htm</b></a> -<dd> Detailed information on how to use Ghostscript, GhostPCL and GhostXPS to convert PostScript, PDF, XPS, PCL or PXL input to Adobe -Portable Document Format (PDF), Adobe PostScript Level 2, Adobe Encapsulated PostScript Level 2, Open XML (XPS) or PCL-XL.</dd></dt> -</dl> - -<dl> -<dt><a name="Psfiles"></a><a href="Psfiles.htm"><b>Psfiles.htm</b></a> -<dd> A description of the PostScript files (other than font files) -distributed with Ghostscript, including initialization routines, utility -programs, and sample printable files.</dd></dt> -</dl> - -<dl> -<dt><a name="THIRDPARTY"></a><a href="thirdparty.htm"><b>thirdparty.htm</b></a> -<dd> -Contains a table of "third party libraries" (that is, code from outwith the -Ghostscript/GhostPDL project) that we import to our project and supply in our -releases. Including the purpose they serve, the version we QA and ship, the -license under which the code distributed and the URL for the "upstream" -project.</dd></dt> -</dl> - -<dl> -<dt><a name="COPYING"></a><a href="COPYING"><b>COPYING</b></a> -<dd> The GNU Affero General Public License, which states the conditions for using -and redistributing GPL Ghostscript.</dd></dt> -</dl> - -<dl> -<dt><a name="Readme"></a><b>Readme.htm</b> -<dd> This document.</dd></dt> -</dl> - -<dl> -<dt><a name="Release"></a><a href="Release.htm"><b>Release.htm</b></a> -<dd> A description of how to prepare and test a Ghostscript release. Of -interest only to developers who want to create new Ghostscript versions for -distribution.</dd></dt> -</dl> - -<dl> -<dt><a name="Source"></a><a href="Source.htm"><b>Source.htm</b></a> -<dd> A guide to the Ghostscript source code, for development and debugging.</dd></dt> -</dl> - -<dl> -<dt><a name="Unix-lpr"></a><a href="Unix-lpr.htm"><b>Unix-lpr.htm</b></a> -<dd> How to set up Ghostscript as a Unix <code>lpr</code> -filter.</dd></dt> -</dl> - -<dl> -<dt><a name="Use"></a><a href="Use.htm"><b>Use.htm</b></a> -<dd> Detailed instructions on how to use Ghostscript, including such -matters as designating an output device; choosing a default paper size; -how Ghostscript finds files, including font files; how it uses environment -variables; notes on specific platforms, including the X Window System; and -command-line options.</dd></dt> -</dl> -</ul> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> - -<small>Ghostscript version 9.56.1, 4 April 2022 - - - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Release.htm b/doc/Release.htm deleted file mode 100644 index bb3c37dd..00000000 --- a/doc/Release.htm +++ /dev/null @@ -1,824 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>How to Prepare a Ghostscript Release</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>How to Prepare a Ghostscript Release</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Introduction">Introduction</a></li> - <li><a href="#Servers">Servers</a></li> - <li> - <ul> - <li><a href="#Development_files">Development sources and bug reports</a></li> - <li><a href="#Distribution">Distribution</a></li> - </ul> - </li> - <li><a href="#Release_numbering">Release numbering</a></li> - <li><a href="#Making_distributions">Making distributions</a></li> - <li> - <ul> - <li><a href="#Preparing_source">Preparing the source code</a></li> - <li><a href="#Testing">Testing</a></li> - <li><a href="#Changelog">Updating the Changelog</a></li> - <li><a href="#Making_Tarballs">Making the source distribution</a></li> - <li><a href="#Testing_on_Windows">Testing on Windows</a></li> - <li><a href="#Windows_distribution">Building the Windows distribution</a></li> - <li><a href="#Finishing_up">Finishing up</a></li> - <li><a href="#Beta_distributions">Beta distributions</a></li> - <li><a href="#Public_releases">Public releases</a></li> - </ul> - </li> - <li><a href="#After_releasing">After releasing</a></li> - <li><a href="#GPL_releases">GPL Ghostscript releases</a></li> - <li> - <ul> - <li><a href="#GPL_code">AGPL code</a></li> - <li><a href="#GPL_after_releasing">After releasing (AGPL)</a></li> - </ul> - </li> - <li><a href="#Fonts">Fonts</a></li> -</ul> - -<!-- [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 instructions on how to <a href="Make.htm">build -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 describes the process for making new Ghostscript releases. -Please note -that while the the license allows anyone to prepare and distribute -releases in accordance with its terms and conditions, this document is -really meant only to document the process used by Artifex Software, Inc. -However, the eventual purpose of this document is to describe -Ghostscript release procedures in enough detail that someone who knows -little about Ghostscript but is generally familiar with the platform on -which the procedure is being carried out can execute the procedures -correctly. So if you add or changing anything to/in this document, -be sure to specify all command lines, file names, etc. in explicit -detail. - -<p> -If you do plan to make your own distribution, please be aware of some items -you will want to change. - -<ul> - -<li>If you make any significant changes, please edit -<code>base/gscdef.c</code> to change <code>GS_PRODUCTFAMILY</code> -and <code>GS_PRODUCT</code> from "GPL Ghostscript" to something else, -in order to avoid confusion with Artifex releases. - -<li>In the same file, you may also want to edit <code>GS_COPYRIGHT</code> -to add your own copyright notice (although you must not remove any -notice that is there). - -<li>You will almost certainly want to edit <code>version.mak</code> to -change the revision date, <code>GS_REVISIONDATE</code>. - -<li>If you want to change the release number, you must change it in all the -places listed under <a href="#Release_numbering">"Release numbering"</a> -below. - -</ul> -<hr> -<h2><a name="Servers"></a>Servers</h2> - -<p> -The GPL Ghostscript files are maintained on sites accessible to -the public. One specific site hosts the active SVN repository for code, -data, and documentation, and the bug report data base; several sites -offer distributions with release numbers, intended for wider -distribution. - -<h3><a name="Development_files"></a>Development sources and bug reports</h3> - -<p> -The primary repository for GPL Ghostscript is <a -href="http://www.ghostscript.com/" class="offsite">ghostscript.com</a>. -Please check there first for any news about releases or current work, -and for information about where to download ghostscript and how to -access the mailing lists. - -Development source access is through <a -href="http://svn.ghostscript.com/" -class="offsite">svn.ghostscript.com</a>. - -<p> -It may also be helpful to -read the SourceForge Ghostscript home page (<a -href="http://sourceforge.net/projects/ghostscript/" -class="offsite">http://sourceforge.net/projects/ghostscript/</a>). - -<h3><a name="Distribution"></a>Distribution</h3> - -<p> -Stable, beta, and development releases are all available from -<blockquote> -<br> -<a href="http://ghostscript.com/download/" -class="offsite">http://ghostscript.com/download/</a> -</blockquote> -<hr> -<h2><a name="Release_numbering"></a>Release numbering</h2> - -<p> -Ghostscript uses a two-part (major.minor) release number. The second part -of the release number is a 2-digit decimal fraction: it counts 00, -01, 02, and so on through 99. - -<ul> - -<li>Release numbers N.0x and N.5x indicate stable versions. -<li>Successive increments generally indicate bug fixes and minor enhancements. -<li>Development, testing and beta releases generally begin with a minor release number that is -a multiple of ten and increment from there. -</ul> - -<p> -Release numbers appear in the following places in the Ghostscript files: - -<ul> - -<li>In <code>Resource/Init/gs_init.ps</code>, as an integer (release -number x100) at the beginning of the -file just after the initial comment blocks. - -<li>In <code>base/version.mak</code>, split into 3 lines. - -<li>In <code>doc/News.htm</code>, in the two headers and their labels and at the very end in -the copyright footer. - -<li>At the foot of most documenation files. However, these are updated mechanically from the value -in <code>News.htm</code> as part of the release process and do not need to be maintained -directly. -</ul> - -<h3>Before a release</h3> - -<p> -The current release number in the development code must be set to the desired value. The increment -from just after the previous release (see below) is sufficient for minor updates. In the case of -major changes or a new stable release, the number will need to be bumped; this is generally done -as the first step of preparing a new release. - -<h3>After a release</h3> - -<p> -After making a release the release number in the repository is -incremented. Thus versions built from svn are always marked with a -future (or unused) release number to avoid confusion. - -<p> -Additionally, After an N.00 or N.50 stable release, a branch is made in svn so that development -can continue independently of changes to the stable series. When this happens, the minor release -number is incremented by 10 (or 20) on the development branch (and by 1 on the new stable branch, -as above) to avoid collisions. - -<p> -While incrementing the release number after making a release may seem -counter-intuitive, it ensures that, at any given time, the version -number alone is sufficient to distinguish between the current SVN -state and a numbered release. -<hr> -<h2><a name="Making_distributions"></a>Making distributions</h2> - -<p> -This document only discusses source distributions. Source distributions -currently can only be made on Linux systems (but it probably wouldn't take -much work to support other Unix systems). Ghostscript as distributed also -often includes executables or other packages for the Windows and MacOS -environments, but upstream does not always produce these, and this -document does not discuss them. - -<p> -To make a source distribution, you will need the scripts and data files in -the <code>toolbin/</code> directory. The instructions below generally -assume that you're invoking the relative to the top level of the source -tree. - -To run the scripts, you will need reasonably current versions of Tcl, -freely available from Scriptics -(<a class="offsite" href="http://www.scriptics.com"><tt>http://www.scriptics.com</tt></a>), and -Python, freely available from <a class="offsite" -href="http://www.python.org"><tt>http://www.python.org</tt></a>. - -<p> -The instructions below also refer to some files that are deliberately -omitted from the public distribution, because they are not freely -redistributable. You will need to provide similar files for your -environment. - -<blockquote><pre> -<code>data/*/*.ps</code> (PostScript files) - needed for smoke testing -</pre></blockquote> - -<h3><a name="Preparing_source"></a>Preparing the source code</h3> - -<p> -If necessary, update the release number by incrementing it as described in -<a href="#Release_numbering">Release numbering</a> above. - -<p> -Update references to the date for release: - -<ul> - -<li>In <code>version.mak</code>, the numeric date. - -<li>In <code>doc/News.htm</code>, in two places, skipping the Id: -line. That is, in parentheses after the <tt>VERSION X.YY</tt> heading, -and in the copyright footer both the year and the release date. - -<li>In <code>psi/dwsetup.rc</code> and <code>psi/winint.mak</code>, -update the year in the embedded copyright notice. - -</ul> - -<p> -We recommend using a UTC release date to avoid timezone skew. - -<p> -Also in <code>doc/News.htm</code>, update the number of the highest -closed bug and the list of open bugs. - -<p> -Check in <code>gscdef.c</code> that the definition of -<code>GS_PRODUCT</code> includes the appropriate one of "DEVELOPMENT -RELEASE", "BETA RELEASE", or neither, and does not include "SVN PRE-RELEASE". - -<p>Run the source-consistency checks from the test suite: - -<blockquote><pre> -toolbin/tests/check_all.py --gsroot=. -</pre></blockquote> -Where the argument of --gsroot is the path to the top level of the -source tree. Fix any problems it indicates, and commit them to svn. - -<p> -Check for patched configuration parameters, <code>#define TEST</code>s, -version/date inconsistencies, and mismatches between the working directory -and the SVN repository by running: - -<blockquote><pre> -toolbin/pre.tcl -</pre></blockquote> - -<p> -This program compares the result of various greps against a check file, -writing the results of grep on one output file and the differences from the -check file on another. See the source code for the default file names. The -important one is the check file, -<code>toolbin/pre.chk</code>. <code>pre.tcl</code> also verifies -that the -right information is in the following places: -<ul> -<li>release number in <code>man/*.1</code>, <code>doc/*.htm</code>, -<code>version.mak</code>, <code>doc/gs-vms.hlp</code>, -<code>Resource/Init/gs_init.ps</code> -<li>revision date in <code>man/*.1</code>, <code>doc/*.htm</code>, -<code>version.mak</code>, <code>doc/gs-vms.hlp</code> -<li>copyright year (if necessary) in <code>gscdef.c</code> -<li>third-party library version number in <code>*.mak</code> -</ul> - -<p> -If necessary, run - -<blockquote><pre> -toolbin/pre.tcl update -</pre></blockquote> - -<p> -to update the version and revision date in the doc files, and then run - -<blockquote><pre> -toolbin/pre.tcl -</pre></blockquote> - -<p> -again. To confirm that everything is updated. You may have to commit to -svn after the update to satify the script that all the dates are -correct. - -<p> -Check the consistency of the source code with the makefiles by -running: - -<blockquote><pre> -toolbin/gsmake.tcl check -</pre></blockquote> - -This script assumes the top level makefile is named '<tt>makefile</tt>'. - -<p> -Fix any problems and commit to svn. - -<h3><a name="Testing"></a>Testing</h3> - -<p> -Edit your top-level the Makefile to set -<blockquote><pre> -FEATURE_DEVS=$(FEATURE_DEVS_ALL) -COMPILE_INITS=1 -</pre></blockquote> - -<p> -This will help catch compilation problems. - -<p> -Run - -<blockquote><pre> -rm obj/* -make -j2 >& make.log -</pre></blockquote> - -<p> -and look for warnings and errors in the log file. - -<p> -Do a smoke test, updating the example paths as necessary: - -<blockquote><pre> -unset GS_DEVICE GS_FONTPATH GS_LIB GS_OPTIONS -./bin/gs -I./lib -I./fonts -dNOPAUSE -dBATCH toolbin/smoke.ps -./bin/gs -I./lib -I./fonts -dNOPAUSE -dBATCH -sDEVICE=bitcmyk\ - -sOutputFile=/dev/null -r600 -dBufferSpace=200000 toolbin/smoke.ps -</pre></blockquote> - -<p> -This reads files named - -<blockquote><pre> -<code>data/misc/*.ps</code> -<code>data/ps/*.ps</code> -<code>data/psl2/*.ps</code> -<code>data/psl3/*.ps</code> -</pre></blockquote> - -<p> -(Edit <code>toolbin/smoke.ps</code> to use other test sets.) -Watch for crashes, unusual error messages, or anomalous displayed output. -If there are any problems, start over from the beginning of the process. - -<p> -Undo the <code>FEATURE_DEVS</code> and <code>COMPILE_INITS</code> -edits. - -<p> -Run - -<blockquote><pre> -svn commit -</pre></blockquote> - -<p> -to ensure the repository is up to date. - -<h3><a name="Changelog"></a>Updating the changelog</h3> - -<p> -Create a new changelog by running - -<blockquote><pre> -svn log -rHEAD:<i>rev</i> --xml --verbose > doc/changelog.xml -</pre></blockquote> - -where <i>rev</i> is the revision number of the branch point for the -previous release. - -<p> -This consolidates all the commit logs since the previous release in a -readable format. You may also wish to remap user names in the -<author/> tags of the output to the real names of the developers. - -<p> -Create the html-format changes and details documents as follows: - -<blockquote><pre> -cd doc -../toolbin/split_changelog.py changelog.xml Changes.htm Details.htm -cd .. -</pre></blockquote> - -<p> -The xml changelog file can now be deleted. - -<p> -[Deprecated]<br> -Copy the contents of News.htm and Changes.htm into a new section in -History8.htm, and News.htm and Details.htm into Details8.htm. Then -update the hyperlinks in History8.htm to point to Details8.htm instead -of Details.htm so these remain valid after the next release.<br> -[/Deprecated]<br> -<br> -As of Ghostscript 9.02, to reduce the pointless duplication of information, -Changes.htm and Details#.htm have been deprecated. - -Copy the contents of Changes.htm into a new section in History9.htm, and ensure -the links in News.htm are updated to reference the new section in History9.htm. - -<p> -Then run - -<blockquote><pre> -svn commit -</pre></blockquote> - -<p> -again to check in the Changes and history files. - -<h3><a name="Making_Tarballs"></a>Making the source distribution</h3> - -<p> -First, tag the versions of the files in svn with the release version -number. - -<blockquote> -<pre><tt>svn cp svn+ssh://svn.ghostscript.com/svn/ghostscript/trunk/gs \ - svn+ssh://svn.ghostscript.com/svn/ghostscript/tags/ghostscript-#.##</tt></pre> -</blockquote> - -If you've already tagged this release (e.g. in making an earlier -release candidate) you'll need to svn rm the old tree first. We -recommend just appending 'rc<i>n</i>' to the end of release candidate -tag names, or a '.<i>n</i>' tiny release number to post-release fixes. - -<p> -Pull a fresh copy for distribution from the repository: - -<blockquote><pre> -<code>svn export http://svn.ghostscript.com/ghostscript/tags/ghostscript-#.##</code> -</pre></blockquote> - - -<p> -Generate the text versions of the README document: - -<blockquote><pre> -cd ghostscript-#.## -lynx -dump -nolist doc/Readme.htm > doc/README -</pre></blockquote> - -<p> -Add copies of needed third-party libraries for the release. Versions -of the normally required ones are included in the repository so this -is only needed when doing special feature releases. - -<p> -For the unix source distributions only, generate the configure -scripts. From the top level directory, run - -<blockquote><pre> -./autogen.sh -make distclean -</pre></blockquote> - -This should create links to <tt>configure.ac</tt> and -<tt>Makefile.in</tt> in the top level directory and -invoke autoconf to create the <tt>configure</tt> script. - -<p> -Also run <tt>make distclean</tt> in the <tt>jasper</tt> subdir to -clean up any incidental config there. If you get a warning, -for example if the build files think they need updating -and not all the tools are available, be sure to run <tt>autoreconf && -make distclean</tt> to avoid version skew issues. -You may also need to manually remove the <tt>autom4te.cache</tt> directory. - -<p> -Move back to directory containing the distribution code and make the -source archives with: - -<blockquote><pre> -tar cvzf ghostscript-#.##.tar.gz ghostscript-#.##/* -zcat ghostscript-#.##.tar.gz | bzip2 -c > ghostscript-#.##.tar.bz2 -</pre></blockquote> - -<p> -This creates the files - -<blockquote><pre> -<code>ghostscript-#.##.tar.gz</code> (main archive) -<code>ghostscript-#.##.tar.bz2</code> (main archive) -</pre></blockquote> - -<p> -The important issue is that the tarballs unpack into a directory -of the same name, and that the code be a pristine copy without -build or .svn housekeeping files. - -<p> -It is also customary to make a <tt>gs###src.zip</tt> archive for the -convenience of windows developers. See below. - -<h3><a name="Testing_on_Windows"></a>Testing on Windows</h3> - -<p> -For Windows testing, you will need, in addition to the files listed -under "<a href="#Preparing_source">Preparing the source</a>" above: -<blockquote><pre> -<code>toolbin/makewin.tcl</code> -</pre></blockquote> - -<p> -The following procedures rely on a large number of MS-DOS batch scripts that -are not discussed here: they are unlikely to be generally useful. - -<p> -Mount the Windows partition on <code>/c</code>, and create the -<code>/c/work</code> directory if needed. - -<p> -Make the zip archive of all files needed for a Windows build, and copy it to -the Windows partition: - -<blockquote><pre> -toolbin/makewin -cp gs###.zip /c/work -</pre></blockquote> - -<p> -Boot into Windows. Unpack the archive: - -<blockquote><pre> -cd \work -unzip -oq gs###.zip -gs### -</pre></blockquote> - -<p> -The <code>gs###.bat</code> script creates some necessary directories, -sets up <code>PATH</code> and <code>GS_LIB</code> for testing, and -makes the <code>gs#.##</code> directory current. - -<p> -Build with the Borland compiler: - -<blockquote><pre> -config bcwin32 -copy /y /b ..\gs\makefile -erase obj\*.* -make > bc.log -</pre></blockquote> - -<p> -Smoke test the executables (both <code>gswin32</code> and -<code>gswin32c</code>), as described above for source distributions. -Then build with the Microsoft compiler: - -<blockquote><pre> -config msvc32 -copy /y /b ..\gs\makefile -erase obj\*.* -nmake > msvc.log -</pre></blockquote> - -<p> -Smoke test these executables too. - -<p> -Building with the Watcom compiler doesn't work, because the -<code>wmake</code> or <code>wmakel</code> program runs out of memory. -However, if it did work, this is how to do it: - -<blockquote><pre> -config watcw32 -copy /y /b ..\gs\makefile -erase obj\*.* -wmake -u > watc.log -</pre></blockquote> - -<p> -Boot back into Linux. If testing in Windows revealed problems, edit the -source files as necessary, and go back to <a -href="#Preparing_source">"Preparing the source code."</a> - -<h3><a name="Windows_distribution"></a>Building the Windows distribution</h3> -<p> -Extract the sources from <code>ghostscript-N.NN.tar.gz</code> -then repackage in a zip file as follows: -<blockquote> -<code>zip -r temp.zip gsN.NN/LICENSE gsN.NN/doc gsN.NN/examples - gsN.NN/icclib gsN.NN/ijs gsN.NN/jasper gsN.NN/jbig2dec gsN.NN/jpeg - gsN.NN/lib gsN.NN/libpng gsN.NN/base gsN.NN/psi gsN.NN/Resource - gsN.NN/zlib</code> -</blockquote> -Unzip converting the line endings to CRLF: -<blockquote> -<code>unzip -a temp.zip<br> -del temp.zip</code> -</blockquote> -Then finally zip up the sources to the distribution file: -<blockquote> -<code>zip -9 -r -X gsNNNsrc.zip gsN.NN</code> -</blockquote> -This method is reasonably portable, and does not convert binary -files such as -<code><a href="../examples/annots.pdf">examples/annots.pdf</a></code>. -<p> -Unzip <code>gsNNNsrc.zip</code>. -The directory must be named <code>gsN.NN</code>. -<p> -Extract the fonts <code>ghostscript-fonts-std-#.##.tar.gz</code> -into a directory <code>fonts</code> adjacent to the -<code>gsN.NN</code> directory. -The fonts are needed in this location for building -the distribution archive later. -<p> -You will need the command line Info-Zip zip program available from -<a href="http://www.info-zip.org/pub/infozip/"> -http://www.info-zip.org/pub/infozip/</a> -Alternatively, the command line version of WinZip -(<code>wzzip.exe</code>) can be used by replacing the -Info-Zip command line options <code>-9 -r</code> -with <code>-ex -P</code> in -<code><a href="../psi/winint.mak">winint.mak</a></code>. -<p> -You will need WinZip Self-Extractor for building the -self extracting archive. This is commercial software. -You may need to update the path <code>WINZIPSE_XE</code> in -<code><a href="../psi/winint.mak">winint.mak</a></code>. -<p> -Unzip the jpeg, libpng and zlib libraries, then make ghostscript -as documented in <a href="Make.htm">Make.htm</a>. -<p> -Run the command <code>nmake archive</code>. This builds the distribution -archive <code>gsNNNw32.exe</code> and an ordinary zip file -<code>gsNNNw32.zip</code> in the parent directory. -If you do not have WinZip Self-Extractor, you can use -<code>nmake zip</code> to make <code>gsNNNw32.zip</code> only. - -<p>Starting with Ghostscript 9.x (Summer 2010), <code>nmake nsis</code> (msvc) -or <code>make nsis</code> (Borland) builds an nsis-based installer -<code>gsNNNw32.exe</code>. This requires -<a href="http://nsis.sourceforge.net/">Nullsoft Scriptable Install System</a>. -You may need to update the path <code>MAKENSIS_XE</code> in -<code><a href="../psi/winint.mak">winint.mak</a></code>. - -<h3><a name="Finishing_up"></a>Finishing up</h3> - -<p> -Upload <code>ghostscript-#.##.tar.*</code> to SourceForge (by anonymous -FTP to <code>upload.sourceforge.net</code>, directory -<code>/incoming</code>), and then post it using the "File Release" -facility in the Ghostscript project. Put the release in the appropriate -package, usually "GPL Ghostscript". -If you are adding executable builds or source archives for other -platforms to an existing source release, please use the same release -date as the source release, not the current date. - -<h3><a name="Beta_distributions"></a>Beta distributions</h3> - -<p> -Do the steps for distributions in general. - -<p> -Upload <code>ghostscript-#.##.tar.*</code> to -<code><a href="http://ghostscript.com/download/" -class="offsite">http://ghostscript.com/download/</a> -</code>. - -<h3><a name="Public_releases"></a>Public releases</h3> - -<p> -Do the steps for distributions in general. - -<ul> - <li>MS Windows source and executables: - -<blockquote><pre> -<code>gs###w32.exe</code> -<code>gs###w64.exe</code> -</pre></blockquote> -</li> -<li>Third-party libraries, as links (upload these if not installed), where -<code>$$$</code> et al. refer to the version number of the library, which -should be the latest compatible release of the library and should be -consistent with the values of and version numbers specifically listed in - the makefiles.</li> -</ul> -<blockquote><pre> -<code>jpegsrc.v$$.tar.gz</code> -> <code>../../3rdparty/jpegsrc.v$$.tar.gz</code> -<code>libpng-$.$.$.tar.gz</code> -> <code>../../3rdparty/libpng-$.$.$.tar.gz</code> -<code>zlib-$.$.$.tar.gz</code> -> <code>../../3rdparty/zlib-$.$.$.tar.gz</code> -<code>jpegsr$$.zip</code> -> <code>../../3rdparty/jpegsr$$.zip</code> -<code>lpng$$$.zip</code> -> <code>../../3rdparty/lpng$$$.zip</code> -<code>zlib$$$.zip</code> -> <code>../../3rdparty/zlib$$$.zip</code> -</pre></blockquote> - -<p>In any case, the names of the links in the distribution directory should reflect -the original name of the upstream file.</p> - -<ul> -<li>Fonts, where <code>$.$$</code> refers to the most recent version -number of the fonts: - -<blockquote><pre> -<code>ghostscript-fonts-other-$.$.tar.gz</code> -> <code>../fonts/ghostscript-fonts-other-$.$.tar.gz</code> -<code>ghostscript-fonts-std-$.$.tar.gz</code> -> <code>../fonts/ghostscript-fonts-std-$.$.tar.gz</code> -</pre></blockquote> -</li> -</ul> - -<p> -(Note that the link names are somewhat inconsistent: some of them retain the -version number of the file being referenced, and some of them use the -Ghostscript release number. This is a historical artifact that might be -changed someday.) - -<p> -E-mail the release announcement using: -<blockquote><pre> -To: gs-announce -</pre></blockquote> - -<p> -Also update the documentation snapshots on the website. -<hr> -<h2><a name="After_releasing"></a>After releasing</h2> - -<p> -Update the release number by incrementing it as described in <a -href="#Release_numbering">Release numbering</a> above. - -<p> -In <code>gscdef.c</code>, edit the definition of -<code>GS_PRODUCT</code> to include "SVN PRE-RELEASE". - -<p> -Edit <code>doc/News.htm</code> to remove all the content. - -<hr> -<h2><a name="Fonts"></a>Fonts</h2> - -<p> -Artifex Software, Inc. distributes a package of the base 35 PostScript -fonts, and a package of other miscellaneous fonts. -<p> -These are included in the Ghostscript release archive. - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/SavedPages.htm b/doc/SavedPages.htm deleted file mode 100644 index 23175b5f..00000000 --- a/doc/SavedPages.htm +++ /dev/null @@ -1,289 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Using Saved Pages ( --saved-pages=... )</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Using Saved Pages ( --saved-pages=... )</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Keywords">Saved Pages control keywords,</a></li> - <li><a href="#Print_Keywords">Printing saved pages.</a></li> - <li><a href="#Examples">Examples.</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> -<p> -Saved pages can be printed in any order, any number of times allowing for copy -collation, manual 'duplex' printing or selecting a subset of pages. -</p> - -<!-- [1.3 end hint] ======================================================== --> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<p> -Many raster printing devices and raster image format devices can use the command -list (clist) to save the rendering information into files or memory based structures. -Usually the clist data is rendered as soon as the page is complete, but it is` -possible to defer rendering, then output (print) after the entire file has been -converted to clist files. -<p> -Since each page is saved separately, the pages can be rendered from the clist -files in any order, any number of times. -<p> -The saved pages are accumulated in clist form as files or in memory. The default -clist storage is specified by the <code>BAND_LIST_STORAGE=</code> macro in the -make file, but if <code>BAND_LIST_STORAGE=file</code>, the clist can be forced -to be in memory using the <code>-sBandListStorage=memory</code> option. -<hr> -<h2><a name="Keywords"></a>Saved Pages control keywords</h2> -<p> -Deferring printing is controlled using the <code>--saved-page=...</code> option. -<p> -The string following the <code>--saved-page=</code> consists of keywords, -separated by white-space, commas, or other non-alphanumeric characters -such as ':', '=', ';'. If more than one keyword is given, the string should -be enclosed in double-quotes (<code>"</code>). -<p> -The '<code>-</code>' (dash), and the '<code>*</code>' asterisk), are used in -page range selections, and cannot be keyword separators. -<p> -Keywords are case independent, thus "<b><code>begin</code></b>", -"<b><code>BEGIN</code></b>", and "<b><code>Begin</code></b>" are all equivalent. -<p> -<dl> -<dt><code>begin</code> -<dd>Begins accumulating pages to a list. The clist data for each page is -saved in files or memory as discussed above, but no rendering is performed. -<p> -If the device was set for rendering into memory, is will be switched to -accumulating the page as clist files, thus <code>-dMaxBitmap</code> and -<code>-dBandingNever</code> will be ignored, as if <code>-dBandingAlways</code> -was specified. -</dl> - -<dl> -<dt><code>flush</code> -<dd>Delete all clist files for all pages on the list, and reset the -list to empty, but remain in <code>saved-pages</code> mode. Subsequent -pages will be added to the list. -</dl> - - <dl> -<dt><code>end</code> -<dd>Flush any list, deleting all clist files for any accumulated pages -and stop accumulating pages, returning to rendering/output as soon as -the page is complete. -<p> -The device may render subsequent pages in memory (page buffer) as -determined by </code>-dMaxBitmap</code> and </code>-dBandingNever</code>. -</dl> - -<dl> -<dt><code>copies </code><em>copy_count</em> -<dd>Set the copy count for the <code>print</code> action. The requested number -of copies will be generated for all subsequent print actions, thus -producing <b>collated</b> copies, rather than multiple copies of -each page as in normal (non-deferred) rendering and output. -<p> -A <code>--saved-pages="copies <em>#</em>"</code> option will be applied to all -print actions until a new <code>copies <em>#</em></code> is encountered -that sets the copy count to a different value. Since the -<code>copies</code> can follow the <code>print</code> command, it is -recommended that only a single <code>copies</code> be in a each -<code>--saved-pages=</code><em>...</em> string. -<p> -Note, that unless <code>-d.IgnoreNumCopies=true</code> is specified -prior to starting <code>saved-pages</code> mode, the copy count for -each page will be saved with each page, and the job will contain the -specified number of copies of each page, as well as producing the -number of collated copies of the job set by the <code>copies</code> -in a <code>--saved-pages=</code><em>...</em> string. -</dl> - -<dl> -<dt><code>print </code><em>print keywords</em> -<dd>Print from the list of saved pages. The <em>print keywords</em> -follwing the <code>print</code> action keyword determine what is -printed, and in what order. The keywords are described in the next -section. -</dl> - - -<h3><a name="Print_Keywords"></a>Printing Saved Pages</h3> - -<p> -The string following the <code>print</code> action keyword determines which pages -from the list are printed, in what order. Any sequence of keywords, page numbers -or page ranges can follow the <code>print</code> keyword. The first control keyword -(other than <code>copies</code>) ends the list of printing keywords. -<p> -As with control keywords, print keywords can be any mixture of upper or lower case, -and print keyword, page numbers and page ranges can be seperated by any non-alphanumeric -character other than '<code>-</code>' or '<code>*</code>'. -<p> -The following are all equivalent: -<blockquote><dl> -<dt><code>1 3 5 - *</code> -<dt><code>1, 3, 5-*</code> -<dt><code>1,3,5-*</code> -</dl></blockquote> - -<dl> -<dt><code>copies </code><em>copy_count</em> -<dd>As mentioned above, the <code>copies</code> keyword and count can follow the <code>print</code> -keyword. See the description of the <code>copies</code> keyword in the previous section. -<p> -The copy count will be applied to the entire sequence of print keywords, so it can -appear anywhere in the sequence of page number, page ranges or print keywords. -</dl> - -<dl> -<dt><code>normal</code> -<dd>Print all of the pages, from the first until the last page in the list. This -keyword is used to print collated copies in the usual page order. This is the -same as the page range: <code>"1 - *"</code> -</dl> - -<dl> -<dt><code>reverse</code> -<dd>Print all of the pages, from the last backwards to the first page in the list. This -keyword is used to print collated copies in the reverse page order. This is the -same as the page range: <code>"* - 1"</code> -</dl> - -<dl> -<dt><code>odd</code> -<dd>Print all odd number pages, from 1 to the last odd numbered page. This keyword, -combined with the <code>even</code> keyword and user interaction to place pages that -were printed into the input tray, can be used for manual duplexing. -</dl> - -<dl> -<dt><code>even</code> -<dd>Print all even number pages, from 2 to the last even numbered page, then if the -list has an odd number of pages print a blank 'pad' page to be the back of the last odd -page. This keyword, combined with the <code>odd</code> keyword and user interaction to -place pages that were printed into the input tray, can be used for manual duplexing. -</dl> - -<dl> -<dt><code>even0pad</code> -<dd>Print all even number pages, from 2 to the last even numbered page, without any -blank 'pad' page as with the <code>even</code> keyword. -</dl> - - <dl> -<dt><em>page_number</em> -<dd>A number not followed by '<code>-</code>' specifies a single page from the -list to be printed. <b> The '<code>*</code>' character represents the last page in -the list, interpreted as a number, either as a single <em>page_number</em> or as the -<em>start_page</em> or <em>end_page</em> in a page range. -</b> -</dl> - - <dl> -<dt><em>start_page</em> <code>-</code> <em>end_page</em> -<dd>A range of pages is two <em>page_number</em>s or <code>*</code> separated by a -'<code>-</code>', optionally surrounded by non-alphanumeric characters other than -'<code>-</code>' which is a special character in page range specifications. The -pages from the <em>start_page</em> to the <em>end_page</em> are printed. -<p> -If the <em>start_page</em> is after the <em>end_page</em>, then the order of the -pages is reversed, from the <em>start_page</em> back to the <em>end_page</em>. -</dl> - -<hr> -<h2><a name="Examples"></a>Examples</h2> -The following examples each print 2 collated copies from the first page to the last page: -<blockquote><dl><code> -<dt>--saved-pages="print: normal, copies=2" -<dt>--saved-pages="print copies=2, normal" -<dt>--saved-pages="copies 2 print normal" -<dt>--saved-pages="print 1-* 1-*" -<dt>--saved-pages="print normal normal" -</code></dl></blockquote> - -Print the last page, followed by all pages in reverse order, then the first page -(print reverse with two copies of the last and first page): -<blockquote><dl><code> -<dt>--saved-pages="print * reverse 1" -<dt> -or- -<dt>--saved-pages="print * * - 1 1" -</code></dl></blockquote> - -Using the command line arguments with a PostScript or PDF input file to print -the odd pages, prompt the operator to reload the printer with the pages that -were printed, then print the even pages: - -<blockquote><dl><code> -<dt>gs -sDEVICE=pgmraw -o /dev/lp0 --saved-pages="begin" examples/annots.pdf \ -<dt>--saved-pages="print odd" \ -<dt>-c "(Move printed pages to the input tray, then press enter.) = flush \ -<dt> (%stdin) (r) file 256 string readline clear" \ -<dt>--saved-pages="print even" -</code></dl></blockquote> - -Print two collated copies of the first file, followed by 5 copies of the second file: -<blockquote><dl><code> -<dt>gs -sDEVICE=pgmraw -o /dev/lp0 --saved-pages="begin" examples/annots.pdf \ -<dt>--saved-pages="copies=2 print normal flush" \ -<dt>examples/colorcir.ps \ -<dt>--saved-pages="copies=5 print normal" -</code></dl></blockquote> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2013-2022 Artifex Software, Inc. All rights -reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, -modified or distributed except as expressly authorized under the terms -of the license contained in the file LICENSE in this distribution. - -For more information about licensing, please visit -http://www.artifex.com/licensing/ -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Search.htm b/doc/Search.htm deleted file mode 100644 index b1644a1a..00000000 --- a/doc/Search.htm +++ /dev/null @@ -1,188 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Search Ghostscript.com</title> - <!-- note: we can't use default.css as some of the CSS there conflicts with Google's injected CSS --> - <style> - - * { - -webkit-tap-highlight-color: rgba(0,0,0,0); - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - } - - html, body, div, span, applet, object, iframe, - h1, h2, h3, h4, h5, h6, p, blockquote, pre, - a, abbr, acronym, address, big, cite, code, - del, dfn, em, img, ins, kbd, q, s, samp, - small, strike, strong, sub, tt, var, - b, u, i, center, - dl, dt, dd, ol, ul, li, - fieldset, form, label, legend, - table, caption, tbody, tfoot, thead, tr, th, td, - article, aside, canvas, details, embed, - figure, figcaption, footer, header, hgroup, - menu, nav, output, ruby, section, summary, - time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; - } - - /* HTML5 display-role reset for older browsers */ - article, aside, details, figcaption, figure, - footer, header, hgroup, menu, nav, section { - display: block; - } - - html, body { - position: relative; - height: 100%; - } - - body { - -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ - -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ - -webkit-user-select: text; /* prevent copy paste, to allow, change 'none' to 'text' */ - color:black; - background:#ffffff; - font-family:"Source Sans Pro", sans-serif; /* 200 = ExtraLight, 300 = Light, 400 = regular, 600 = semi-bold, 700 = bold, 900 = black */ - font-weight:400; - font-size:16px; - margin:0px; - padding:0px; - } - - main .outer { - max-width: 1280px; - margin: 0px auto 100px; - padding-top: 50px; - } - - main .inner { - padding: 20px; - } - - header { - position: fixed; - width: 100%; - height:50px; - background: #0075cf url(language-bindings/images/ghostscript.png) 10px center no-repeat; - background-size: 30px 30px; - color: #fff; - line-height: 50px; - text-indent: 50px; - z-index: 1; - display: flex; - justify-content: space-between; - } - - header .search { - width: 50px; - height:50px; - background: #0075cf url(images/icon-search.png) center center no-repeat; - background-size: 50px 50px; - } - - a { - text-decoration: none; - color: #0075cf; - } - - i { - font-style: italic; - } - - p { - line-height: 24px; - } - - header h1 { - font-size:24px; - font-weight:600; - color: #fff; - text-decoration: none; - } - - header a h1 { - color: #fff; - } - - h1 { - font-size:40px; - font-weight:600; - } - - /* Dark mode */ - @media (prefers-color-scheme: dark) { - - body { - background-color: #000; - color: white; - } - - a { - text-decoration: none; - color: #289df6; - } - - blockquote { - border: 1px solid #efefef; - } - - } - - </style> - - <script async src="https://cse.google.com/cse.js?cx=056ea92e7af6e50cc"></script> - -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Search documentation</h1> - - -<div class="gcse-search"></div> -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Source.htm b/doc/Source.htm deleted file mode 100644 index 82b03bee..00000000 --- a/doc/Source.htm +++ /dev/null @@ -1,430 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Guide to Ghostscript Source Code</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Guide to Ghostscript Source Code</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Overview">Conceptual overview</a></li> - <li><a href="#PostScript_interpreter">PostScript Interpreter</a></li> - <li><a href="#PDF_interpreter">PDF interpreter</a></li> - <li><a href="#Graphics_library">Graphics library</a></li> - <li> - <ul> - <li><a href="#Drivers">Device drivers</a></li> - <li><a href="#Platform_specific_code">Platform-specific code</a></li> - </ul> - </li> - <li><a href="#Makefiles">Makefiles</a></li> -</ul> - -<!-- [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 documents on <a href="Make.htm">how to build -Ghostscript</a> from source, <a href="C-style.htm">Ghostscript C coding -guidelines</a>, <a href="Drivers.htm">drivers</a>, the -<a href="Lib.htm">Ghostscript library</a> and <a href="Install.htm">how to -install Ghostscript</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Overview"></a>Conceptual overview</h2> - -<p> -The Ghostscript source code is divided conceptually as follows: - -<blockquote><table> -<tr> - <th align="left" colspan="2">PostScript interpreter:</th> - </tr> -<tr> - - <td>PostScript operators</td> - - <td><code>z</code>*<code>.h</code> and <code>z</code>*<code>.c</code></td> - </tr> -<tr> - - <td>Other interpreter code</td> - - <td><code>i</code>*<code>.h</code> and <code>i</code>*<code>.c</code></td> - </tr> -<tr> - - <td>PostScript code</td> - - <td><code>gs_</code>*<code>.ps</code></td> - </tr> -<tr> - <th align="left" colspan="2">PDF interpreter:</th> - </tr> -<tr> - - <td>PostScript code</td> - - <td><code>pdf_</code>*<code>.ps</code></td> - </tr> -<tr> - <th align="left" colspan="2">Graphics library:</th> - </tr> -<tr> - - <td>Main library code</td> - - <td><code>g</code>*<code>.h</code> and <code>g</code>*<code>.c</code></td> - </tr> -<tr> - - <td>Streams</td> - - <td><code>s</code>*<code>.h</code> and <code>s</code>*<code>.c</code></td> - </tr> -<tr> - - <td><a href="#Drivers">Device drivers</a></td> - - <td><code>gdev</code>*<code>.h</code> and <code>gdev</code>*<code>.c</code></td> - </tr> -<tr> - - <td><a href="#Platform_specific_code">Platform-specific code</a></td> - - <td><code>gp</code>*<code>.h</code> and <code>gp</code>*<code>.c</code></td> - </tr> -</table></blockquote> - -<hr> - -<h2><a name="PostScript_interpreter"></a>PostScript Interpreter</h2> - -<p> -<code>gs.c</code> is the main program for the interactive language -interpreter; <code>gserver.c</code> is an alternative main program that -is a rudimentary server. If you configure Ghostscript as a server rather -than an interactive program, you will use <code>gserver.c</code> instead -of <code>gs.c</code>. - -<p> -Files named <code>z</code>*<code>.c</code> are Ghostscript operator -files. The names of the files generally follow the section headings of the -operator summary in section 6.2 (Second Edition) or 8.2 (Third Edition) of -the PostScript Language Reference Manual. Each operator XXX is implemented -by a procedure named <code>z</code>XXX, for example, -<code>zfill</code> and <code>zarray</code>. - -<p> -Files named <code>i</code>*<code>.c</code>, and *<code>.h</code> -other than <code>g</code>*<code>.h</code>, are the rest of the -interpreter. See the makefile for a little more information on how the -files are divided functionally. - -<p> -The main loop of the PostScript interpreter is the <code>interp</code> -procedure in <code>interp.c</code>. When the interpreter is reading -from an input file, it calls the token scanner in -<code>iscan</code>*<code>.c</code>. - -<p> -<code>idebug.c</code> contains a lot of debugger-callable routines -useful for printing PostScript objects when debugging. - -<hr> - -<h2><a name="PDF_interpreter"></a>PDF interpreter</h2> - -<p> -The PDF interpreter is written entirely in PostScript. Its main loop is -the <code>.pdfrun</code> procedure in <code>pdf_base.ps</code>. When -the PDF interpreter is configured into the build, it redefines the -"<code>run</code>" operator to test whether the file is a PDF file. -This redefinition is near the beginning of <code>pdf_main.ps</code>. - -<hr> - -<h2><a name="Graphics_library"></a>Graphics library</h2> - -<p> -Files beginning with <code>gs</code>, <code>gx</code>, or -<code>gz</code> (both <code>.c</code> and <code>.h</code>), other -than <code>gs.c</code> and <code>gserver.c</code>, are the -Ghostscript library. Files beginning with <code>gdev</code> are device -drivers or related code, also part of the library. Other files beginning -with <code>g</code> are library files that don't fall neatly into either -the kernel or the driver category. - -<p> -Files named <code>s</code>*<code>.c</code> and -<code>s</code>*<code>.h</code> are a flexible stream package, -including the Level 2 PostScript "filters" supported by Ghostscript. See -<code>stream.h</code>, <code>scommon.h</code>, and -<code>strimpl.h</code> for all the details. - -<h3><a name="Drivers"></a>Device drivers</h3> - -<p> -The interface between the graphics library and device drivers is the only -really well documented one in all of Ghostscript: see the -<a href="Drivers.htm">documentation on drivers</a>. - -<p> -In addition to many real device and file format drivers listed in -<code>devs.mak</code> and <code>contrib.mak</code>, a number of -drivers are used for internal purposes. You can search -<code>lib.mak</code> for files named -<code>gdev</code>*<code>.c</code> to find almost all of them. - -<p> -Drivers are divided into "printer" drivers, which support banding, and -non-printer drivers, which don't. The decision whether banding is -required is made (by default on the basis of how much memory is available) -in the procedure <code>gdev_prn_alloc</code> in -<code>gdevprn.c</code>: it implements this decision by filling the -virtual procedure table for the printer device in one of two different -ways. - -<p> -A good simple "printer" (bandable) driver to read is -<code>gdevmiff.c</code>: it's less than 100 lines, of which much is -boilerplate. There are no simple non-printer drivers that actually drive -devices: probably the simplest non-printer driver for reading is -<code>gdevm8.c</code>, which implements 8-bit-deep devices that only -store the bits in memory. - -<h3><a name="Platform_specific_code"></a>Platform-specific code</h3> - -<p> -There are very few platform dependencies in Ghostscript. Ghostscript deals -with them in three ways: - -<ul> -<li>Files named *<code>_.h</code> substitute for the corresponding -<code><</code>*<code>.h></code> file by adding conditionals -that provide a uniform set of system interfaces on all platforms. - -<li>The file <code>arch.h</code> contains a set of -mechanically-discovered platform properties like byte order, size of -<code>int</code>, etc. These properties, <b>not</b> the names of -specific platforms, are used to select between different algorithms or -parameters at compile time. - -<li>Files named <code>gp</code>*<code>.h</code> define interfaces -that are intended to be implemented differently on each platform, but whose -specification is common to all platforms. -</ul> - -<p> -The platform-specific implementations of the -<code>gp</code>*<code>.h</code> interfaces have names of the form -"<code>gp_</code><em>{platform}</em><code>.c</code>, specifically -(this list may be out of date): - -<blockquote><table> -<tr> - <th colspan="2">Platform-specific interfaces</th> - </tr> -<tr> - <th align="left">Routine</th> - <th align="left">Platform</th> - </tr> -<tr> - <td><code>gp_dosfb.c</code></td> - <td>DOS</td> - </tr> -<tr> - <td><code>gp_dosfs.c</code></td> - <td>DOS and MS Windows</td> - </tr> -<tr> - <td><code>gp_itbc.c</code></td> - <td>DOS, Borland compilers</td> - </tr> -<tr> - <td><code>gp_iwatc.c</code></td> - <td>DOS, Watcom or Microsoft compiler</td> - </tr> -<tr> - <td><code>gp_msdos.c</code></td> - <td>DOS and MS Windows</td> - </tr> -<tr> - <td><code>gp_ntfs.c</code></td> - <td>MS Windows NT</td> - </tr> -<tr> - <td><code>gp_os2.c</code></td> - <td>OS/2</td> - </tr> -<tr> - <td><code>gp_os9.c</code></td> - <td>OS-9</td> - </tr> -<tr> - <td><code>gp_unifs.c</code></td> - <td>Unix, OS-9, and QNX</td> - </tr> -<tr> - <td><code>gp_unix.c</code></td> - - <td>Unix and QNX</td> - </tr> -<tr> - <td><code>gp_vms.c</code></td> - - <td>VMS</td> - </tr> -<tr> - <td><code>gp_win32.c</code></td> - - <td>MS Windows NT</td> - </tr> -</table></blockquote> - -<p> -If you are going to extend Ghostscript to new machines or operating -systems, check the *<code>_.h</code> files for <code>ifdef</code> on -things other than <code>DEBUG</code>. You should probably plan to make -a new makefile and a new <code>gp_</code>XXX<code>.c</code> file. - -<hr> - -<h2><a name="Makefiles"></a>Makefiles</h2> - -<p> -This section is only for advanced developers who need to integrate -Ghostscript into a larger program at build time. - -<p> -NOTE: THIS SECTION IS INCOMPLETE. IT WILL BE IMPROVED IN A LATER REVISION. - -<p> -The Ghostscript makefiles are meant to be organized according to the -following two principles: - -<ul> - -<li>All the parameters that vary from platform to platform appear in the -top-level makefile for a given platform. ("Platform" = OS + compiler + -choice of interpreter vs. library) - -<li>All the rules and definitions that can meaningfully be shared among more -than 1 platform appear in a makefile that is "included" by a makefile -(normally the top-level makefile) for those platforms. -</ul> - -<p> -Thus, for example: - -<ul> - -<li>Rules and definitions shared by all builds are in -<code>gs.mak</code>. - -<li>Rules and definitions specific to the library (on all platforms) are in -<code>lib.mak</code>. In principle this could be merged with -<code>gs.mak</code>, but we wanted to leave open the possibility that -<code>gs.mak</code> might be useful with hypothetical interpreter-only -products. - -<li>Stuff specific to interpreters (on all platforms) is in -<code>int.mak</code>. - -<li>Stuff specific to all Unix platforms should be in a single -<code>unix.mak</code> file, but because <code>make</code> sometimes -cares about the order of definitions, and because some of it is shared with -DV/X, it got split between <code>unix-aux.mak</code>, -<code>unix-end.mak</code>, <code>unixhead.mak</code>, -<code>unixinst.mak</code>, and <code>unixlink.mak</code>. - -</ul> - -<p> -For MS-DOS and MS Windows builds, there should be: - -<ul> - -<li>A makefile for all MS OS (DOS or Windows) builds, for all - compilers and products. - -<li>Perhaps a makefile for all MS-DOS builds, for all compilers and -products, although since Watcom is the only such compiler we're likely to -support this may be overkill. - -<li>A makefile for all MS Windows builds, for all compilers and products. - -<li>A makefile for all Watcom builds (DOS or Windows), for all products. - -<li>A top-level makefile for the Watcom DOS interpreter product. - -<li>A top-level makefile for the Watcom Windows interpreter product. - -<li>A top-level makefile for the Watcom DOS library "product". - -<li>A top-level makefile for the Watcom Windows library "product". - -<li>A makefile for all Borland builds (DOS or Windows), for all - products. - -</ul> - -<p> -and so on. - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Unix-lpr.htm b/doc/Unix-lpr.htm deleted file mode 100644 index 063ed25a..00000000 --- a/doc/Unix-lpr.htm +++ /dev/null @@ -1,279 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Setting Up a Unix 1pr Filter for Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Setting Up a Unix 1pr Filter for Ghostscript</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Overview">Overview</a></li> - <li><a href="#What_it_can_do">What it can do</a></li> - <li><a href="#Setting_up">Setting it up</a></li> - <li> - <ul> - <li><a href="#Editing_device_list">Editing the device list <code>DEVICES</code></a></li> - <li> - <ul> - <li><a href="#Field_bpp">Field 1: bits per pixel</a></li> - <li><a href="#Field_colours">Field 2: colours</a></li> - <li><a href="#Field_dq">Field 3: dual queues</a></li> - <li><a href="#Device_example">Example definition of <code>DEVICES</code></a></li> - </ul> - </li> - <li><a href="#Editing_filter_list">Editing the filter list</a></li> - <li><a href="#Editing_printer_port">Editing the printer port and type</a></li> - <li><a href="#Modifying_printcap_insert">Modifying <code>printcap.insert</code></a></li> - <li><a href="#Multiple_queues">Single or dual queues</a></li> - </ul> - </li> - <li><a href="#Bugs">Bugs</a></li> - <li><a href="#Authors">Authors</a></li> -</ul> - -<!-- [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 <a href="Use.htm">usage documentation</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Overview"></a>Overview</h2> - -<p> -"How do I set up Ghostscript to provide PostScript queues in a standard lpr -environment on Unix systems?" is a Frequently Asked Question amongst -Ghostscript users. The two shell scripts described by this document are -designed to make this task a little easier. They are</p> - -<blockquote><dl> -<dt><code>unix-lpr.sh</code></dt> -<dd>a flexible, multi-option print filter</dd> - -<dt><code>lprsetup.sh</code></dt> -<dd>A shell script which sets up soft links and creates a template insert -for the <code>printcap</code> file</dd> -</dl></blockquote> - -<hr> - -<h2><a name="What_it_can_do"></a>What it can do</h2> - -<p> -The print filter resides in the Ghostscript installation directory (often -<code>/usr/local/share/ghostscript</code>, but may be something else at -your installation), together with a dummy filter directory containing -various soft links which point to the filter. It offers the following -features:</p> - -<ul> -<li>Multiple devices supported by a single filter</li> -<li>Multiple bit-depths for the same device</li> -<li>Multiple number of colours for the same device</li> -<li>Direct (single-queue) and indirect (two-queue) setup</li> -<li>Support for the standard preprocessing filters if you have the -corresponding (whatever)-to-PostScript translators</li> -<li>Redirection of diagnostic and programmed output to a logfile in -the spooling directory</li> -<li>Maintaining of printer accounting records of the numbers of pages -printed by each user (compatible with the <code>pac</code> command)</li> -<li>Straightforward editing for further customisation</li> -</ul> - -<hr> - -<h2><a name="Setting_up"></a>Setting it up</h2> - -<p> -The <code>lprsetup.sh</code> script needs to have two lines edited -before running, to set the printer devices to use and the list of filters -available. With this information, it</p> - -<ul> -<li>creates a "<code>filt</code>" subdirectory under the -Ghostscript installation directory</li> -<li>creates the links in this directory which enable the filter to -determine the parameters for running Ghostscript</li> -<li>automatically generates <code>printcap</code> entries which should -need only a little editing before adding to your system -<code>printcap</code> file</li> -</ul> - -<h3><a name="Editing_device_list"></a>Editing the device list <tt>DEVICES</tt></h3> - -<p> -At the top of <code>lprsetup.sh</code> is a line of the form -<code>DEVICES=</code><em>{list}</em>. Replace the example list with -your own list of devices. Each entry is the name of a device, followed by -three more optional fields, separated by dots "<code>.</code>".</p> - -<h4><a name="Field_bpp"></a>Field 1: bits per pixel</h4> - -<p> -The first field is required only if the printer device understands the <a -href="Devices.htm#deskjet_parameters"><code>-dBitsPerPixel=</code> -switch</a>, which applies only to colour devices. For a particular number -<b><em>N</em></b> of bits per pixel, add the suffix <b><em>.N</em></b> to -the device name, for instance <code>cdj500.3</code>, -<code>cdj500.24</code>, etc.</p> - -<h4><a name="Field_colours"></a>Field 2: colours</h4> - -<p> -The second field is required only if the printer device understands the -setting of the <code>Colors</code> device parameter (as in -<code>-dColors=</code>), which applies only to colour devices (and at -present is only supported by the <code>bjc</code>* family of drivers). -For a particular number <b><em>N</em></b> of colours, suffix -<b><em>.N</em></b> to the device name, such as <code>bjc600.24.3</code>, -<code>bjc600.8.1</code> etc.</p> - -<h4><a name="Field_dq"></a>Field 3: dual queues</h4> - -<p> -The third field is required in order to use two separate queues for the -device, a "raw" queue and a PostScript queue (see -"<a href="#Multiple_queues">Single or dual queues</a>" below). If you want -dual queues, add the suffix <code>.dq</code> ("dual queue") to the name, -whether or not a <a href="#Field_bpp">bits-per-pixel suffix</a> has already -been added.</p> - -<h4><a name="Device_example"></a>Example definition of -<tt>DEVICES</tt></h4> - -<p> -Thus the following list supports a <code>cdj550</code> device at three -different bit depths (24 bpp, 3 bpp and 1 bpp), with a dual queue (that is, -a separate queue for the raw data); a monochrome <code>deskjet</code> -device with a single queue; and a <code>djet500</code> device using a -separate queue:</p> - -<blockquote><code> -DEVICES="cdj550.24.dq cdj550.3.dq cdj550.1.dq deskjet djet500.dq" -</code></blockquote> - -<h3><a name="Editing_filter_list"></a>Editing the filter list</h3> - -<p> -The standard list contains only the generic "<code>if</code>" filter, -but a commented-out list shows other filters which may be available. If -you wish to use the support for these filters, you may need to edit the -<code>bsd-if</code> file to add to the <code>PATH</code> the -directories where the translators are stored, or to change the names of the -filters if yours are different. The <code>bsd-if</code> script is -supplied with an example setup using Transcript (a commercial package from -Adobe), and PBMPLUS, a freeware package by Jef Poskanzer and others.</p> - -<h3><a name="Editing_printer_port"></a>Editing the printer port and -type</h3> - -<p> -You can set the port and port type (parallel or printer) for an attached -printer, but for remote printers you'll have to modify the -<tt>printcap.insert</tt> file yourself.</p> - -<h3><a name="Modifying_printcap_insert"></a>Modifying -<tt>printcap.insert</tt></h3> - -<p> -Running <code>lprsetup.sh</code> generates a file -<code>printcap.insert</code> which has a template setup for your -printer queues. It cannot guarantee to do the whole job, and you will -probably need to consult your system documentation and edit this file -before you add it to your <code>printcap</code> file. The file has good -defaults for serial printers, as these often cause problems in getting -binary data to the printer. However, you may need to change the baud rate, -or the handshaking method. Only a small change is required in the -<code>printcap</code> file to use a networked remote printer instead of -an attached printer, and an example is given in -<code>printcap.insert</code>.</p> - -<h3><a name="Multiple_queues"></a>Single or dual queues</h3> - -<p> -If you wish to provide a PostScript-only queue (for example, so that all -pages printed go through accounting), and the printer port is local to the -host machine, a single queue is appropriate -- Ghostscript simply converts -PostScript into the printer's native data format and sends it to the -port. But if the printer is on a remote networked machine, or if you need to -send raw printer data to the printer, you must use two queues. Simply -specify the <a href="#Field_dq">"<code>.dq</code>" option</a> above.</p> - -<hr> - -<h2><a name="Bugs"></a>Bugs</h2> - -<p> -You must have write access to the Ghostscript installation directory for -<code>lprsetup.sh</code> to create the filter directory and soft links.</p> - -<p> -If you have several different values of bits per pixel for the same device, -you must list all instances of that device as adjacent items in the -<a href="#Editing_device_list"><code>DEVICES</code></a> device -list. If you do not, <code>printcap.insert</code> will contain multiple -entries for the same device, which is not supported.</p> - -<hr> - -<h2><a name="Authors"></a>Authors</h2> - -<p> -This material was contributed by George Cameron. Yves Arrouye -<<a href="mailto:yves.arrouye@usa.net">yves.arrouye@usa.net</a>> -is responsible for the number-of-colours part of the script.</p> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/Use.htm b/doc/Use.htm deleted file mode 100644 index 42857c3e..00000000 --- a/doc/Use.htm +++ /dev/null @@ -1,5437 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>How to Use Ghostscript</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>How to Use Ghostscript</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Invoking">Invoking Ghostscript</a></li> - <li> - <ul> - <li><a href="#Help_command">Help at the command line: <code>gs -h</code></a></li> - </ul> - </li> - <li><a href="#Output_device">Selecting an output device</a></li> - <li> - <ul> - <li><a href="#Output_resolution">Output resolution</a></li> - <li><a href="#File_output">Output to files</a></li> - <li> - <ul> - <li><a href="#One_page_per_file">One page per file</a></li> - </ul> - </li> - <li><a href="#Paper_size">Choosing paper size</a></li> - <li><a href="#Change_default_size">Changing the installed default paper size</a></li> - </ul> - </li> - <li><a href="#Pipes">Interacting with pipes</a></li> - <li><a href="#PDF">Using Ghostscript with PDF files</a></li> - <li> - <ul> - <li><a href="#PDF_switches">Switches for PDF files</a></li> - <li><a href="#PDF_problems">Problems interpreting a PDF file</a></li> - <li><a href="#PDF_stdin">PDF files from standard input</a></li> - </ul> - </li> - <li><a href="#EPS">Using Ghostscript with EPS files</a></li> - <li><a href="#SPOT">Using Ghostscript with overprinting and spot colors</a></li> - <li><a href="#Finding_files">How Ghostscript finds files</a></li> - <li> - <ul> - <li><a href="#PS_resources">Finding PostScript Level 2 resources</a></li> - <li><a href="#Font_lookup">Font lookup</a></li> - <li><a href="#CIDFonts">CID fonts</a></li> - <li><a href="#CIDFontSubstitution">CID font substitution</a></li> - <li><a href="#UnicodeTT">Using Unicode True Type fonts</a></li> - <li><a href="#Temp_files">Temporary files</a></li> - </ul> - </li> - <li><a href="#Platforms">Notes on specific platforms</a></li> - <li> - <ul> - <li><a href="#Word size">Word size (32 or 64 bits)</a></li> - <li><a href="#Unix">Unix</a></li> - <li><a href="#VMS">VMS</a></li> - <li> - <ul> - <li><a href="#VMS_X_Windows">Using X Windows on VMS</a></li> - </ul> - </li> - <li><a href="#MS_Windows">MS Windows</a></li> - <li><a href="#X_Windows">X Windows</a></li> - <li> - <ul> - <li><a href="#X_resources">X resources</a></li> - <li><a href="#X_server_bugs">Working around bugs in X servers</a></li> - <li><a href="#X_device_parameters">X device parameters</a></li> - </ul> - </li> - <li><a href="#SCO_Unix">SCO Unix</a></li> - </ul> - </li> - - <li><a href="#Options">Command line options</a></li> - <li> - <ul> - <li><a href="#General_switches">General switches</a></li> - <li> - <ul> - <li><a href="#Input_control">Input control</a></li> - <li><a href="#File_searching">File searching</a></li> - <li><a href="#Parameters">Setting parameters</a></li> - <li><a href="#Quiet">Suppress messages</a></li> - </ul> - </li> - <li><a href="#Parameter_switches">Parameter switches (<code>-d</code> and <code>-s</code>)</a></li> - <li> - <ul> - <li><a href="#Rendering_parameters">Rendering parameters</a></li> - <li><a href="#Page_parameters">Page parameters</a></li> - <li><a href="#Font_related_parameters">Font-related parameters</a></li> - <li><a href="#Resource_related_parameters">Resource-related parameters</a></li> - <li><a href="#Interaction_related_parameters">Interaction-related parameters</a></li> - <li><a href="#Output_selection_parameters">Device and output selection parameters</a></li> - <li><a href="#EPS_parameters">EPS parameters</a></li> - <li><a href="#Deferred_Page_Rendering">Deferred Page Rendering</a></li> - <li><a href="#ICC_color_parameters">ICC color parameters</a></li> - <li><a href="#Other_parameters">Other parameters</a></li> - </ul> - </li> - </ul> - </li> - <li><a href="#Improving_performance">Improving performance</a></li> - <li><a href="#Environment_variables">Summary of environment variables</a></li> - - <li><a href="#Debugging">Debugging</a></li> - <li> - <ul> - <li><a href="#Debug_switches">Debug Switches</a></li> - <li><a href="#Visual_trace">Visual Trace</a></li> - </ul> - </li> - <li><a href="#Known_paper_sizes">Appendix: Paper sizes known to Ghostscript</a></li> - <li><a href="#X_font_mappings">Appendix: X default font mappings</a></li> - <li> - <ul> - <li><a href="#Standard_X_server_fonts">Standard X servers</a></li> - <li> - <ul> - <li><a href="#X_regular_fonts">Regular fonts</a></li> - <li><a href="#X_symbol_fonts">Symbol fonts</a></li> - <li><a href="#X_dingbat_fonts">Dingbat fonts</a></li> - </ul> - </li> - <li><a href="#OpenWindows_fonts">Sun OpenWindows</a></li> - </ul> - </li> - <li><a href="#FAPI_run">Appendix: Running Ghostscript with third-party - font renderers</a></li> - -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a> and, if necessary, how to - <a href="Install.htm">install Ghostscript</a>.</p> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Invoking"></a>Invoking Ghostscript</h2> - -<p>This document describes how to use the command line Ghostscript client. -Ghostscript is also used as a general engine inside other applications (for viewing files for example). -Please refer to the documentation for those applications for using Ghostscript in other contexts.</p> - -<p><a name="Command_line"></a> The command line to invoke Ghostscript is -essentially the same on all systems, although the name of the executable -program itself may differ among systems. For instance, to invoke -Ghostscript on unix-like systems type:</p> - -<blockquote> - <pre><code>gs</code> [options] {filename 1} ... [options] {filename <em>N</em>} ... -</pre></blockquote> - -<p>Here are some basic examples. The details of how these work are described below.</p> - -<p>To view a file:</p> -<blockquote><pre>gs -dSAFER -dBATCH document.pdf</pre></blockquote> -<p>You'll be prompted to press <em>return</em> between pages.</p> - -<p>To convert a figure to an image file:</p> -<blockquote><pre>gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -dGraphicsAlphaBits=4 \ - -sOutputFile=tiger.png tiger.eps</pre></blockquote> - -<p>To render the same image at 300 dpi:</p> -<blockquote><pre>gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r300 \ - -sOutputFile=tiger_300.png tiger.eps -</pre></blockquote> - -<p>To render a figure in grayscale:</p> -<blockquote><pre>gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pnggray -sOutputFile=figure.png figure.pdf -</pre></blockquote> - -<p>To rasterize a whole document:</p> -<blockquote><pre>gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pgmraw -r150 \ - -dTextAlphaBits=4 -sOutputFile='paper-%00d.pgm' paper.ps</pre></blockquote> - -<p>There are also a number of utility scripts for common to convert a PostScript document to PDF:</p> -<blockquote><pre>ps2pdf file.ps</pre></blockquote> -<p>The output is saved as file.pdf.</p> - -<p>There are other utility scripts besides <code>ps2pdf</code>, including <code>pdf2ps</code>, <code>ps2epsi</code>, <code>pdf2dsc</code>, <code>ps2ascii</code>, -<code>ps2ps</code> and <code>ps2ps2</code>. These just call Ghostscript with the appropriate -(if complicated) set of options. You can use the 'ps2' set with eps files.</p> - -<p> -Ghostscript is capable of interpreting PostScript, encapsulated PostScript -(EPS), DOS EPS (EPSF), and Adobe Portable Document Format (PDF). The interpreter reads and executes the files in sequence, using the method described under "<a href="#File_searching">File searching</a>" to find them.</p> - -<p>The interpreter runs in interactive mode by default. After processing the files given on the command line (if any) it reads further lines of PostScript language commands from the primary input stream, normally the keyboard, interpreting each line separately. To quit the interpreter, type "<code>quit</code>". The <code>-dBATCH -dNOPAUSE</code> options in the examples above disable the interactive prompting. The interpreter also quits gracefully if it encounters end-of-file or control-C.</p> - -<p> -The interpreter recognizes many options. An option may appear anywhere in the command line, and applies to all files named after it on the line. Many of them include "<code>=</code>" -followed by a parameter. The most important are described in detail here. Please see the reference sections on <a href="#Options">options</a> and <a href="Devices.htm">devices</a> for a more complete listing.</p> - -<h3><a name="Help_command"></a>Help at the command line: <code>gs -h</code></h3> - -<p> -You can get a brief help message by invoking Ghostscript with the -<code>-h</code> or <code>-?</code> switch, like this:</p> - -<blockquote><pre> -gs -h -gs -? -</pre></blockquote> - -<p> -The message shows for that version of the Ghostscript executable:</p> - -<ul> -<li>the version and release information</li> -<li>the general format of the command line</li> -<li>a few of the most useful options</li> -<li>the formats it can interpret</li> -<li>the available output devices</li> -<li>the search path</li> -<li>the bug report address</li> -</ul> - -<p> -On other systems the executable may have a different name:</p> - -<blockquote><table> -<tr> - <th align="left">System</th> - <th align="left">Invocation Name</th></tr> -<tr><td>Unix</td> - <td><code>gs</code></td></tr> -<tr><td>VMS</td> - <td><code>gs</code></td></tr> -<tr><td>MS Windows 95 and later</td> - <td><code>gswin32.exe</code><br/> - <code>gswin32c.exe</code><br/> - <code>gswin64.exe</code><br/> - <code>gswin64c.exe</code></td> -</tr> -<tr><td>OS/2</td> - <td><code>gsos2</code></td></tr> -</table></blockquote> -<p>On Windows, the two digit number indicates the word length of the system for which the binary was built (so -<code>gswin32.exe</code> is for x86 Windows systems, whilst <code>gswin64.exe</code> is for x86_64 Windows -systems). And the <code>"c"</code> suffix indicates a Windows console based binary (note that the -<code>"display device"</code> window will still appear). -<hr> -<h2><a name="Output_device"></a>Selecting an output device</h2> - -<p> -Ghostscript has a notion of 'output devices' which handle saving or displaying the results in a particular format. Ghostscript comes with a diverse variety of such devices supporting vector and raster file output, screen display, driving various printers and communicating with other applications.</p> - -<p> -The command line option '<code>-sDEVICE=</code><em>device</em>' selects which output device Ghostscript should use. If this option isn't given the default device (usually a display device) is used. Ghostscript's built-in help message (<code>gs -h</code>) lists the available output devices. For complete description of the devices distributed with Ghostscript and their options, please see the <a href="Devices.htm">devices section</a> of the documentation.</p> - -<p><a name="Device_output"></a> -Note that this switch must precede the name of the first input file, and -only its first use has any effect. For example, for printer output in a -configuration that includes an Epson printer driver, instead of just -<code>'gs myfile.ps'</code> you might use</p> - -<blockquote> - <code>gs -sDEVICE=epson myfile.ps</code> -</blockquote> - -<p><a name="GS_DEVICE"></a> -The output device can also be set through the <code>GS_DEVICE</code> environment variable.</p> - -<p> -Once you invoke Ghostscript you can also find out what devices are available by typing -'<code>devicenames ==</code>' at the interactive prompt. -You can set the output device and process a file from the interactive prompt as well:</p> - - -<blockquote><pre> -(epson) selectdevice -(myfile.ps) run -</pre></blockquote> - -<p>All output then goes to the Epson printer instead of the display until you -do something to change devices. You can switch devices at any time by -using the <code>selectdevice</code> procedure, for -instance like one of these:</p> - -<blockquote><pre> -(x11alpha) selectdevice -(epson) selectdevice -</pre></blockquote> - -<h3><a name="Output_resolution"></a>Output resolution</h3> - -<p> -Some printers can print at several different resolutions, letting you -balance resolution against printing speed. To select the resolution on -such a printer, use the <code>-r</code> switch:</p> - -<blockquote> - <code>gs -sDEVICE=</code><em>printer</em><code> -r</code><em>XRES</em><code>x</code><em>YRES</em> -</blockquote> - -<p>where <em>XRES</em> and <em>YRES</em> are the requested number of dots (or pixels) per inch. Where the two resolutions are same, as is the common case, you can simply use <code>-r</code><em>res</em>.</p> - -<p> -The <code>-r</code> option is also useful for controlling the density of pixels when rasterizing to an image file. It is used this way in the examples at the beginning of this document.</p> - -<h3><a name="File_output"></a>Output to files</h3> - -<p> -Ghostscript 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 printer.</p> - -<p> -To send the output to a file, use the <code>-sOutputFile=</code> switch or the <a href="#o_option"><code>-o</code> switch</a> (below). -For instance, to direct all output into the file <code>ABC.xyz</code>, use</p> - -<blockquote><code> -gs -sOutputFile=ABC.xyz -</code></blockquote> - -<p> -When printing on MS Windows systems, output normally goes directly to the printer, <code>PRN</code>. On Unix and VMS systems it normally goes to a temporary file which is sent to the printer in a separate step. When using Ghostscript 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.</p> - -<p> -Ghostscript also accepts the special filename '<code>-</code>' which indicates the output should be written to standard output (the command shell).</p> - -<p> -Be aware that filenames beginning with the character <code>%</code> have a special meaning in PostScript. If you need to specify a file name that actually -begins with <code>%</code>, you must prepend the <code>%os%</code> filedevice explicitly. For example to output to a file named <code>%abc</code>, you need to specify</p> - -<blockquote> -<code>gs -sOutputFile=%os%%abc</code> -</blockquote> - -<p>Please see <a href="Language.htm">Ghostscript and the PostScript Language</a> and the PostScript Language Reference Manual for more details on <code>%</code> and filedevices.</p> - -<p><b> -Note that on MS Windows systems, the <code>%</code> character also has a special meaning for the command processor (shell), so you will have to double it.</b></p> - -<blockquote> -<code>gs -sOutputFile=%%os%%%%abc</code> (on MS Windows) -</blockquote> - -<p><b> -Note, some devices (e.g. pdfwrite, ps2write, ...) only write the output file -upon exit, but changing the OutputFile device parameter will cause these -devices to emit the pages received up to that point and then open the new -file name given by OutputFile. -</b></p> -<p> -For example, in order to create two PDF files from a single invocation of -ghostscript the following can be used:</p> -<blockquote> -<code>gs -sDEVICE=pdfwrite -o tiger.pdf examples/tiger.eps -c "<< /OutputFile (colorcir.pdf) >> setpagedevice" -f examples/colorcir.ps</code> -</blockquote> - -<h4><a name="One_page_per_file"></a>One page per file</h4> - -<p> -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 Ghostscript to put each page of output in a -series of similarly named files. To do this place a template -'<code>%d</code>' in the filename which Ghostscript will replace with the -page number.</p> - -<p> -<b>Note: Since the <code>%</code> character is used to precede the page number -format specification, in order to represent a file name that contains a <code>%</code>, -double <code>%</code> characters must be used. For example for the file <code>my%foo</code> -the OutputFile string needs to be <code>my%%foo</code>.</b></p> - -<p> -The format can in fact be more involved than a simple '<code>%d</code>'. -The format specifier is of a form similar to the C <code>printf</code> format. -The general form supported is:</p> -<pre><code> %[flags][width][.precision][l]type - - where: flags is one of: #+- - type is one of: diuoxX -</code></pre> - -<p>For more information, please refer to documentation on the C printf format -specifications. Some examples are:</p> - -<blockquote><dl> - <dt><code>-sOutputFile=ABC-%d.png</code></dt> - <dd>produces '<code>ABC-1.png</code>', ... , '<code>ABC-10.png</code>', ..</dd> - <dt><code>-sOutputFile=ABC-%03d.pgm</code></dt> - <dd>produces '<code>ABC-001.pgm</code>', ... , '<code>ABC-010.pgm</code>', ...</dd> - <dt><code>-sOutputFile=ABC_p%04d.tiff</code></dt> -<dd>produces '<code>ABC_p0001.tiff</code>', ... , '<code>ABC_p0510.tiff</code>', ... , '<code>ABC_p5238.tiff</code>'</dd> -</dl></blockquote> - - -<p><b> -Note, however that the one page per file feature may not supported by all devices. -Also, since some devices write output files when opened, there may be an extra -blank page written (pdfwrite, ps2write, eps2write, pxlmono, pxlcolor, ...). -</b></p> - -<p> -As noted above, when using MS Windows console (command.com or cmd.exe), you -will have to double the <code>%</code> character since the <code>%</code> is used by -that shell to prefix variables for substitution, e.g.,</p> - -<blockquote><code> -gswin32c -sOutputFile=ABC%%03d.xyz -</code></blockquote> - -<h4><a name="o_option"></a>-o option:</h4> -<p> -As a convenient shorthand you can use the <code>-o</code> option followed by the output -file specification as discussed above. The <code>-o</code> option also sets the -<a href="#Interaction_related_parameters"><code>-dBATCH</code> and <code>-dNOPAUSE</code> options</a>. -This is intended to be a quick way to invoke ghostscript to convert one or more -input files.</p> - -<p>For instance, to convert somefile.ps to JPEG image files, one per page, use:</p> - -<blockquote><code> -gs -sDEVICE=jpeg -o out-%d.jpg somefile.ps -</code></blockquote> - -<p>is equivalent to:</p> - -<blockquote><code> -gs -sDEVICE=jpeg -sOutputFile=out-%d.jpg -dBATCH -dNOPAUSE somefile.ps -</code></blockquote> - -<h3><a name="Paper_size"></a>Choosing paper size</h3> - -<p> -Ghostscript is distributed configured to use U.S. letter paper as its -default page size. There are two ways to select other paper sizes from the -command line:</p> - -<ul> - -<li> -If the desired paper size is listed in the section on <a -href="#Known_paper_sizes">paper sizes known to Ghostscript</a> below, you -can select it as the default paper size for a single invocation of -Ghostscript by using the <code>-sPAPERSIZE=</code> switch, for instance:<p> - - -<blockquote><code> --sPAPERSIZE=a4<br> --sPAPERSIZE=legal -</code></blockquote> -</li> - -<li> -Otherwise you can set the page size using the -pair of switches:<p> - - -<blockquote> -<code>-dDEVICEWIDTHPOINTS=</code><em>w</em> -<code>-dDEVICEHEIGHTPOINTS=</code><em>h</em> -</blockquote> - -<p>Where <em>w</em> be the desired paper width and <em>h</em> be the -desired paper height in <em>points</em> (units of 1/72 of an inch).</p> -</li> -</ul> - -<p> -Individual documents can (and often do) specify a paper size, which takes -precedence over the default size. To force a specific paper size and -ignore the paper size specified in the document, select a paper size as -just described, and also include the -<a href="#FIXEDMEDIA"><code>-dFIXEDMEDIA</code> switch</a> on the -command line.</p> - -<p> -The default set of paper sizes will be included in the <code>currentpagedevice</code> -in the <code>InputAttributes</code> dictionary with each paper size as -one of the entries. The last entry in the dictionary (which has numeric keys) -is a non-standard (Ghostscript extension) type of PageSize where the array -has four elements rather than the standard two elements. This four element -array represents a page size range where the first two elements are the lower -bound of the range and the second two are the upper bound. By default these -are [0, 0] for the lower bound and [16#fffff, 16#fffff] for the upper bound.</p> -<p> -The range type of PageSize is intended to allow flexible page size sepcification -for non-printer file formats such as JPEG, PNG, TIFF, EPS, ...</p> -<p> -For actual printers, either the entire <code>InputAttributes</code> dictionary -should be replaced or the range type entry should not be included. To simplify -using the default page sizes in the <code>InputAttributes</code> dictionary, -the command line option <code>-dNORANGEPAGESIZE</code> can be used. Using -this option will result in automatic rotation of the document page if the requested -page size matches one of the default page sizes.</p> - -<p> -When the <a href="#FIXEDMEDIA"><code>-dFIXEDMEDIA</code> switch</a> is given on the -command line, the <code>InputAttributes</code> dictionary will only be populated -with the single page size. This allows the <code>-dPSFitPage</code> option to fit -the page size requested in a PostScript file to be rotated, scaled and centered -for the best fit on the specified page.</p> - -<h3><a name="Change_default_size"></a>Changing the installed default paper size</h3> - -<p> -You can change the installed default paper size on an installed version of Ghostscript, by editing the initialization file <code>gs_init.ps</code>. -This file is usually in the <code>Resource/Init</code> directory somewhere in the search path. See the section on <a href="#Finding_files">finding files</a> for details.</p> - -<p> -Find the line</p> - -<blockquote><pre> -% /DEFAULTPAPERSIZE (a4) def -</pre></blockquote> - -<p> -Then to make A4 the default paper size, uncomment the line to change -this to</p> - -<blockquote><pre> -/DEFAULTPAPERSIZE (a4) def -</pre></blockquote> - -<p> -For <code>a4</code> you can substitute any -<a href="#Known_paper_sizes">paper size Ghostscript knows</a>.</p> - -<p> -This supecedes the previous method of uncommenting the line -<code>% (a4) ...</code>.</p> - -<p> -Sometimes the initialization files are compiled into Ghostscript and cannot be changed.</p> - -<p> -On Windows and some Linux builds, the default paper size will be -selected to be a4 or letter depending -on the locale.</p> -<hr> -<h2><a name="Pipes"></a>Interacting with pipes</h2> - -<p> -As noted above, input files are normally specified on the command -line. However, one can also "pipe" input into Ghostscript from another -program by using the special file name '<code>-</code>' which is interpreted as standard input. Examples:</p> - -<blockquote> -{<em>some program producing ps</em>} <code>| gs</code> [options] <code>-</code> -<br> -<code>zcat paper.ps.gz</code> <code>| gs</code> <code>-</code> -</blockquote> - -<p> -When Ghostscript finishes reading from the pipe, it quits rather than -going into interactive mode. Because of this, options and files after the '<code>-</code>' in the command line will be ignored.</p> - -<p> -On Unix and MS Windows systems you can send output to a pipe in the same way. For example, to pipe the output to <code>lpr</code>, use the command</p> - -<blockquote><code> - <b>gs -q -sOutputFile=- |</b> lpr -</code></blockquote> - -<p> -In this case you must also use the <a href="#Quiet"><code>-q</code> -switch</a> to prevent Ghostscript from writing messages to standard output -which become mixed with the intended output stream.</p> -<p> -Also, using the <b>-sstdout=%stderr</b> option is useful, particularly with -input from PostScript files that may print to stdout.</p> - -<p> -Similar results can be obtained with the <code>%stdout</code> and <code>%pipe%</code> filedevices. The example above would become</p> - -<blockquote><code> - <b>gs -sOutputFile=%stdout -q |</b> lpr -</code></blockquote> -or -<blockquote><code> - <b>gs -sOutputFile=%pipe%</b>lpr -</code></blockquote> - -<p>(again, doubling the <code>%</code> character on MS Windows systems.)</p> - -<p> -In the last case, <code>-q</code> isn't necessary since Ghostscript handles the pipe itself and messages sent to stdout will be printed as normal.</p> -<hr> -<h2><a name="PDF"></a>Using Ghostscript with PDF files</h2> - -<p> -Ghostscript is normally built to interpret both PostScript and PDF files, examining each file to determine automatically whether its contents are PDF or PostScript. All the normal switches and procedures for interpreting PostScript files also apply to PDF files, with a few exceptions. In addition, the -<code>pdf2ps</code> utility uses Ghostscript to convert PDF to (Level 2) PostScript.</p> - -<h3><a name="PDF_switches"></a>Switches for PDF files</h3> - -<p>Here are some command line options specific to PDF</p> - - <dl> -<dt><code>-dNEWPDF</code></dt> -<dd>From release 9.55.0 Ghostscript incorporates two complete PDF interpreters; the original -long-standing interpreter is written in PostScript but there is now a new interpreter written -in C. -<p>At present the old PostScript-based interpreter remains the default, in future releases the -new C-based interpreter will become the default, though we would encourage people to experiment -with the new interpreter and send us feedback. While there are two interpreters the command-line -switch NEWPDF will allow selection of the existing interpreter when false and the new interpreter -when true.</p> - -</dd> -</dl> - - <dl> -<dt><code>-dPDFFitPage</code></dt> -<dd>Rather than selecting a PageSize given by the PDF MediaBox, BleedBox (see -dUseBleedBox), -TrimBox (see -dUseTrimBox), ArtBox (see -dUseArtBox), or CropBox (see -dUseCropBox), -the PDF file will be scaled to fit the current device page size -(usually the default page size). -<p> -This is useful for creating fixed size images of PDF files that may have -a variety of page sizes, for example thumbnail images.</p> -<p> -This option is also set by the <code>-dFitPage</code> option.</p> -</dd> -</dl> - -<dl> - <dt><code>-dPrinted</code></dt> - <dt><code>-dPrinted=false</code></dt> - <dd>Determines whether the file should be displayed or printed using the - "screen" or "printer" options for annotations and images. With - <code>-dPrinted</code>, the output will use the file's "print" - options; with <code>-dPrinted=false</code>, the output will use the - file's "screen" options. If neither of these is specified, the output will - use the screen options for any output device that doesn't have an - <code>OutputFile</code> parameter, and the printer options for - devices that do have this parameter.</dd> -</dl> - -<dl> - <dt><code>-dUseBleedBox</code></dt> - <dd>Sets the page size to the BleedBox rather than the MediaBox. - defines the region to which the contents of the page should be - clipped when output in a production environment. This may include - any extra bleed area needed to accommodate the physical limitations - of cutting, folding, and trimming equipment. The actual printed page - may include printing marks that fall outside the bleed box.</dd> -</dl> - -<dl> - <dt><code>-dUseTrimBox</code></dt> - <dd>Sets the page size to the TrimBox rather than the MediaBox. - The trim box defines the intended dimensions of the finished page - after trimming. Some files have a TrimBox that is smaller than the - MediaBox and may include white space, registration or cutting marks - outside the CropBox. Using this option simulates appearance of the - finished printed page.</dd> -</dl> - -<dl> - <dt><code>-dUseArtBox</code></dt> - <dd>Sets the page size to the ArtBox rather than the MediaBox. - The art box defines the extent of the page's meaningful content - (including potential white space) as intended by the page's creator. - The art box is likely to be the smallest box. It can be useful - when one wants to crop the page as much as possible - without losing the content.</dd> -</dl> - -<dl> - <dt><code>-dUseCropBox</code></dt> - <dd>Sets the page size to the CropBox rather than the MediaBox. - Unlike the other "page boundary" boxes, CropBox does not have a - defined meaning, it simply provides a rectangle to which the - page contents will be clipped (cropped). By convention, it is - often, but not exclusively, used to aid the positioning of content - on the (usually larger, in these cases) media.</dd> -</dl> - -<dl> - <dt><code>-sPDFPassword=</code><em>password</em></dt> - <dd>Sets the user or owner password to be used in decoding encrypted - PDF files. For files created with encryption method 4 or earlier, the - password is an arbitrary string of bytes; with encryption method 5 or - later, it should be text in either UTF-8 or your locale's character - set (Ghostscript tries both).</dd> -</dl> - -<dl> - <dt><code>-dShowAnnots=false</code></dt> - <dd> - Don't enumerate annotations associated with the page - <code>Annots</code> key. Annotations are shown by default. -<p> In addition, finer control is available by defining an array -<code>/ShowAnnotTypes</code>. Annotation types listed in this array will -be drawn, whilst those not listed will not be drawn.</p> -<p> To use this feature: -<code>-c "/ShowAnnotTypes [....] def" -f <input file></code> -<br> Where the array can contain one or more of the following names: -<code>/Stamp</code>, <code>/Squiggly</code>, <code>/Underline</code>, <code>/Link</code>, <code>/Text</code>, <code>/Highlight</code>, <code>/Ink</code>, <code>/FreeText</code>, <code>/StrikeOut</code> and <code>/stamp_dict</code>.</p> -<p> For example, adding the follow to the command line: -<code>-c "/ShowAnnotTypes [/Text /UnderLine] def" -f <input file></code> - <br> would draw only annotations with the subtypes "Text" and "UnderLine"</p> - </dd> -</dl> - -<dl> - <dt><code>-dShowAcroForm=false</code></dt> - <dd> - Don't show annotations from the Interactive Form Dictionary (AcroForm dictionary). - By default, AcroForm processing is now enabled because Adobe Acrobat does this. This option - is provided to restore the previous behavior which corresponded to older Acrobat.</dd> -</dl> - -<dl> - <dt><code>-dNoUserUnit</code></dt> -<dd> - Ignore <code>UserUnit</code> parameter. This may be useful for backward - compatibility with old versions of Ghostscript and Adobe Acrobat, - or for processing files with large values of <code>UserUnit</code> - that otherwise exceed implementation limits.</dd> -</dl> - -<dl> - <dt><code>-dRENDERTTNOTDEF</code></dt> - <dd> - If a glyph is not present in a font the normal behaviour is to use the /.notdef - glyph instead. On TrueType fonts, this is often a hollow sqaure. Under some - conditions Acrobat does not do this, instead leaving a gap equivalent to the - width of the missing glyph, or the width of the /.notdef glyph if no /Widths - array is present. Ghostscript now attempts to mimic this undocumented feature - using a user parameter <code>RenderTTNotdef</code>. The PDF interpreter sets this - user parameter to the value of <code>RENDERTTNOTDEF</code> in systemdict, - when rendering PDF files. To restore rendering of /.notdef glyphs from TrueType fonts in PDF files, set this parameter to true.</dd> -</dl> - -<p>These command line options are no longer specific to PDF, but have some specific differences with PDF files</p> - -<dl> - <dt><code>-dFirstPage=</code><em>pagenumber</em></dt> - <dd>Begin on the designated page of the document. - Pages of all documents in PDF collections are numbered sequentionally.</dd> -</dl> - -<dl> - <dt><code>-dLastPage=</code><em>pagenumber</em></dt> - <dd>Stop after the designated page of the document. - Pages of all documents in PDF collections are numbered sequentionally.</dd> -</dl> - -<dl> - <dt><code>-sPageList=</code><em>pagenumber</em></dt> - -<dd>There are three possible values for this; even, odd or a list of pages to be processed. -A list can include single pages or ranges of pages. -Ranges of pages use the minus sign '-', individual pages and ranges of pages are separated -by commas ','. A trailing minus '-' means process all remaining pages. For example; -<p><blockquote><pre> --sPageList=1,3,5 indicates that pages 1, 3 and 5 should be processed. --sPageList=5-10 indicates that pages 5, 6, 7, 8, 9 and 10 should be processed. --sPageList=1,5-10,12- indicates that pages 1, 5, 6, 7, 8, 9, 10 and 12 onwards should be processed. -</pre></blockquote> -Note: Use of PageList overrides FirstPage and/or LastPage, if you set these as well as PageList they will be ignored. The - list of pages should be given in increasing order, you cannot process pages out of order and inserting higher numbered pages before lower numbered - pages in the list will generate an error. -</p> - -<p>The PDF interpreter and the other language interpreters handle these in slightly different ways. Because -PDF files enable random access to pages in the document the PDF inerpreter only interprets and renders -the required pages. PCL and PostScript cannot be handled in ths way, and so all the pages must be interpreted. -However only the requested pages are rendered, which can still lead to savings in time. Be aware that -using the '%d' syntax for OutputFile does not reflect the page number in the original document. If you -chose (for example) to process even pages by using <code>-sPageList=even</code>, then the output of -<code>-sOutputFile=out%d.png</code> would still be -out0.png, out1.png, out2.png etc...... -</p> -<p> -Because the PostScript and PCL interpreters cannot determine when a document terminates, sending multple -files as input on the command line does not reset the PageList between each document, each page in the second and -subsequent documents is treated as following on directly from the last page in the first document. The PDF -interpreter, however, does not work this way. Since it knows about individual PDF files the PageList -is applied to each PDF file separately. So if you were to set <code>-sPageList=1,2</code> and - then send two PDF files, the result would be pages 1 and 2 from the first file, and then pages 1 and 2 from the second - file. The PostScript interpreter, by contrast, would only render pages 1 and 2 from the first file. This means you must - exercise caution when using this switch, and probably should not use it at all when processing a mixture of PostScript - and PDF files on the same command line. -</p> -<p> -The XPS language like the PDF language allows random access to pages. The XPS interpreter handles all the PageList cases -discussed above. It also handles cases such as: -<blockquote><pre> --sPageList=1,2,1,2 indicates repeated pages. Pages processed in order 1, 2, 1, 2. --sPageList=10-5 indicates pages will be processed in the order 10, 9, 8, 7, 6, 5. --sPageList=1-,-1 indicates first processing from page 1 to end and then from end to page 1. -</pre></blockquote> -In addition, the XPS interpreter allows the use of a -dLastPage < -dFirstPage. In this -case the pages will be processed backwards from LastPage to FirstPage. -</p> - -</dd> -</dl> - -<h3><a name="PDF_problems"></a>Problems interpreting a PDF file</h3> - -<p> -Occasionally you may try to read or print a 'PDF' file that -Ghostscript doesn't recognize as PDF, even though the same file -<b><em>can</em></b> be opened and interpreted by an Adobe Acrobat viewer. -In many cases, this is because of incorrectly generated PDF. Acrobat -tends to be very forgiving of invalid PDF files. Ghostscript tends to -expect files to conform to the standard. For example, even though -valid PDF files must begin with <code>%PDF</code>, Acrobat will -scan the first 1000 bytes or so for this string, and ignore any preceding -garbage.</p> - -<p> -In the past, Ghostscript's policy has been to simply fail with an -error message when confronted with these files. This policy has, no -doubt, encouraged PDF generators to be more careful. However, we now -recognize that this behavior is not very friendly for people who just -want to use Ghostscript to view or print PDF files. Our new policy is -to try to render broken PDF's, and also to print a warning, so that -Ghostscript is still useful as a sanity-check for invalid files.</p> - -<h3><a name="PDF_stdin"></a>PDF files from standard input</h3> - -<p> -The PDF language, unlike the PostScript language, inherently requires -random access to the file. -If you provide PDF to standard input using the -special filename <a href="#Pipes">'<code>-</code>'</a>, -Ghostscript will copy it to a temporary file before interpreting the PDF.</p> -<hr> -<h2><a name="EPS"></a>Using Ghostscript with EPS files</h2> -<p> -Encapsulated PostScript (EPS) files are intended to be incorporated -in other PostScript documents and may not display or print on their -own. An EPS file must conform to the Document Structuring Conventions, -must include a <code>%%BoundingBox</code> line to indicate the -rectangle in which it will draw, must not use PostScript commands -which will interfere with the document importing the EPS, -and can have either zero pages or one page. -Ghostscript has support for handling EPS files, but requires -that the <code>%%BoundingBox</code> be in the header, -not the trailer. -To customize EPS handling, see <a href="#EPS_parameters">EPS parameters</a>.</p> - -<p> -For the official description of the EPS file format, please -refer to the Adobe documentation in their tech note #5002. It -is available from: -<a href="http://partners.adobe.com/public/developer/ps/index_specs.html" -class="offsite"> -http://partners.adobe.com/public/developer/ps/index_specs.html</a></p> -<hr> -<h2><a name="SPOT"></a>Using Ghostscript with overprinting and spot colors</h2> - -<p> -In general with PostScript and PDF interpreters, the handling of -<b>overprinting</b> and <b>spot colors</b> depends upon the -process color model of the <a href="#Output_device">output device</a>. Devices -that produce gray or RGB output have an <b>additive</b> process color model. -Devices which produce CMYK output have a <b>subtractive</b> process color model. -Devices may, or may not, have support for spot colors.</p> - -<blockquote><i> -Note: The differences in appearance of files with overprinting and spot colors -caused by the differences in the color model of the output device are part of the -PostScript and PDF specifications. They are not due to a limitation in the -implementation of Ghostscript or its output devices. -</i></blockquote> - -<p> -With devices which use a subtractive process color model, both PostScript -and PDF allow the drawing of objects using colorants (inks) for one or more planes -without affecting the data for the remaining colorants. Thus the inks for one -object may <code>overprint</code> the inks for another object. In some cases -this produces a transparency like effect. (The effects of overprinting should -not be confused with the PDF 1.4 blending operations which are supported for -all output devices.) Overprinting is not allowed for devices with an additive -process color model. With files that use overprinting, the appearance of the -resulting image can differ between devices which produce RGB output versus devices -which produce CMYK output. Ghostscript automatically overprints (if needed) -when the output device uses a subtractive process color model. For example, -if the file is using overprinting, differences can be seen in the appearance -of the output from the <a href="Devices.htm#TIFF">tiff24nc and tiff32nc devices</a> -which use an RGB and a CMYK process color models.</p> - -<p> -Most of the Ghostscript <a href="Devices.htm">output devices</a> do not have -file formats which support spot colors. Instead spot colors are converted using -the tint transform function contained within the color space definition.. However -there are several devices which have support for spot colors. The PSD format -(Adobe Photoshop) produced by the <a href="Devices.htm#PSD">psdcmyk device</a> -contains both the raster data plus an equivalent CMYK color for each spot color. -This allows Photoshop to simulate the appearance of the spot colors. The <a href="Devices.htm#display_device">display -device (MS Windows, OS/2, gtk+)</a> can be used with different color models: -Gray, RGB, CMYK only, or CMYK plus spot colors (separation). The display device, -when using its CMYK plus spot color (separation) mode, also uses an equivalent -CMYK color to simulate the appearance of the spot color. The -<a href="Devices.htm#TIFF">tiffsep -device</a> creates output files for each separation (CMYK and any spot colors -present). It also creates a composite CMYK file using an equivalent CMYK color -to simulate the appearance of spot colors. The -<a href="Devices.htm#XCF">xcfcmyk device</a> -creates output files with spot colors placed in separate alpha channels. (The -XCF file format does not currently directly support spot colors.)</p> - -<p> -Overprinting with spot colors is not allowed if the tint transform function -is being used to convert spot colors. Thus if spot colors are used with overprinting, -then the appearance of the result can differ between output devices. One result -would be obtained with a CMYK only device and another would be obtained with -a CMYK plus spot color device. In a worst case situation where a file has overprinting -with both process (CMYK) and spot colors, it is possible to get three different -appearances for the same input file using the -<a href="Devices.htm#TIFF">tiff24nc</a> (RGB), -<a href="Devices.htm#TIFF">tiff32nc</a> (CMYK), and -<a href="Devices.htm#TIFF">tiffsep</a> (CMYK plus spot colors) devices.</p> - -<blockquote><i> -In Adobe Acrobat, viewing of the effects of overprinting is enabled by the -'Overprint Preview' item in the 'Advanced' menu. This feature is not available -in the free Acrobat Reader. The free Acrobat Reader also uses the tint transform -functions to convert spot colors to the appropriate alternate color space. -</i></blockquote> - - -<hr> - -<h2><a name="Finding_files"></a>How Ghostscript finds files</h2> - -<p> -When looking for initialization files (<code>gs_*.ps</code>, -<code>pdf_*.ps</code>), font files, the <code>Fontmap</code> file, -files named on the command line, and resource files, Ghostscript first tests whether the -file name specifies an absolute path.</p> - -<blockquote><table> -<tr><th colspan="2">Testing a file name for an absolute path</th></tr> -<tr><th align="left">System</th> - - <th align="left">Does the name ...</th></tr> -<tr><td colspan="2"></td></tr> -<tr><td valign="top">Unix</td> - - <td>Begin with <code><u>/</u></code> ?</td></tr> -<tr><td valign="top">MS Windows</td> - - <td>Have <code><u>:</u></code> as its second character, or - begin with <code><u>/</u></code>, <code><u>\</u></code>, - or <code><u>//servername/share/</u></code> ?</td></tr> -<tr><td valign="top">VMS</td> - - <td>Contain a node, device, or root specification?</td></tr> -</table></blockquote> - -<p>If the test succeeds, Ghostscript tries to open the file -using the name given. Otherwise it tries directories in this order:</p> - -<ol> -<li>The current directory if enabled by the -<a href="#P-_switch"><code>-P</code> switch</a>;</li> - -<li>The directories specified by <a href="#I_switch"><code>-I</code> -switches</a> in the command line, if any;</li> - -<li>The directories specified by the <code>GS_LIB</code> -environment variable, if any;</li> - -<li>If built with COMPILE_INITS=1 (currently the default build) the files in the -<code>%rom%Resource/</code> and <code>%rom%iccprofiles/</code> directories are -built into the executable.</li> - -<li>The directories specified by the <code>GS_LIB_DEFAULT</code> macro -(if any) in the makefile when this executable was built.</li> -</ol> - -<p> -<code>GS_LIB_DEFAULT</code>, -<code>GS_LIB</code>, and the -<code>-I</code> parameter may specify either a single -directory or a list of directories separated by a character appropriate for -the operating system ("<code>:</code>" on Unix systems, -"<code>,</code>" on VMS systems, and -"<code>;</code>" on MS Windows systems). -By default, Ghostscript no longer searches the current directory first -but provides <a href="#P_switch"><code>-P</code> switch</a> for a degree -of backward compatibility.</p> - -<p> -Note that Ghostscript does not use this file searching algorithm for the -<code>run</code> or <code>file</code> operators: for these operators, it -simply opens the file with the name given. To run a file using the searching -algorithm, use <code>runlibfile</code> instead of <code>run</code>.</p> - -<h3><a name="PS_resources"></a>Finding PostScript Level 2 resources</h3> - -<p> -Adobe specifies that resources are installed in a single directory. -Ghostscript instead maintains a list of resource directories, -and uses an extended method for finding resource files.</p> - -<p> -The search for a resource file depends on whether -the value of the system parameter <code>GenericResourceDir</code> -specifies an absolute path. The user may set it as explained in -<a href="#Resource_related_parameters">Resource-related parameters</a>.</p> - -<p> -If the user doesn't set the system parameter <code>GenericResourceDir</code>, -or use the <code>-sGenericResourceDir=</code> command line option, Ghostscript -creates a default value for it by looking on the directory paths explained in -<a href="#Finding_files">How Ghostscript finds files</a>, excluding the current directory. -The first path with <code>Resource</code> in it is used, including any prefix -up to the path separator character following the string <code>Resource</code>. -For example, when COMPILE_INITS=1 (the current default build), if the first path -is <code>%rom%Resource/Init/</code>, then the <code>GenericResourceDir</code> -systemparam will be set to <code>%rom%Resource/</code> by default.</p> - -<p> -If the value of the system parameter <code>GenericResourceDir</code> -is an absolute path (the default), -Ghostscript assumes a single resource directory. -It concatenates :</p> - -<ol> -<li>The value of the system parameter <code>GenericResourceDir</code>;</li> -<li>The name of the resource category (for instance, <code>CMap</code>);</li> -<li>The name of the resource instance (for instance, <code>Identity-H</code>).</li> -</ol> - -<p>If the value of the system parameter <code>GenericResourceDir</code> -is not an absolute path, -Ghostscript assumes multiple resource directories. -In this case it concatenates :</p> - -<ol> -<li>A directory listed in the section -<a href="#Finding_files">How Ghostscript finds files</a>, -except the current directory;</li> - -<li>The value of the system parameter <code>GenericResourceDir</code>;</li> - -<li>The name of the resource category (for instance, <code>CMap</code>);</li> - -<li>The name of the resource instance (for instance, <code>Identity-H</code>)</li> -</ol> - -<p>Due to possible variety of the part 1, the first successful combination is used. -For example, if the value of the system parameter <code>GenericResourceDir</code> -is the string <code>../Resource/</code> -(or its equivalent in the file path syntax of the underlying platform), -Ghostscript searches for <code>../Resource/CMap/Identity-H</code> -from all directories listed in -<a href="#Finding_files">How Ghostscript finds files</a>. -So in this example, if the user on a Windows platform specifies -the command line option <code>-I.;../gs/lib;c:/gs8.50/lib</code>, -Ghostscript searches for <code>../gs/Resource/CMap/Identity-H</code> and -then for <code>c:/gs8.50/Resource/CMap/Identity-H</code>.</p> - -<p> -To get a proper platform dependent syntax Ghostscript inserts -the value of the system parameter -<code>GenericResourcePathSep</code> (initially -"<code>/</code>" on Unix and Windows, "<code>:</code>" on MacOS, -"<code>.</code>" or "<code>]</code>" on OpenVMS). -The string <code>../Resource</code> is replaced with a -platform dependent equivalent.</p> - -<p> -In the case of multiple resource directories, -the default <code>ResourceFileName</code> procedure retrieves either a path -to the first avaliable resource, or if the resource is not available it -returns a path starting with <code>GenericResourceDir</code>. -Consequently Postscript installers of Postscript resources -will overwrite an existing resource or add a new one to the first resource directory.</p> - -<p> -To look up fonts, after exhausting the search method described in <a href="#Font_lookup">the -next section</a>, it concatenates together</p> - -<ol> -<li>the value of the system parameter -<code>FontResourceDir</code> (initially -<code>/Resource/Font/</code>)</li> - -<li>the name of the resource font (for instance, <code>Times-Roman</code>)</li> -</ol> - -<p> -Note that even although the system parameters are named "somethingDir", they -are not just plain directory names: they have "<code>/</code>" on the -end, so that they can be concatenated with the category name or font name.</p> - -<h3><a name="Font_lookup"></a>Font lookup</h3> - -<p> -Ghostscript has a slightly different way to find the file containing a font -with a given name. This rule uses not only the search path defined by -<code>-I</code>, <code>GS_LIB</code>, and -<code>GS_LIB_DEFAULT</code> <a href="#Finding_files">as described -above</a>, but also the directory that is the value of the -<code>FontResourceDir</code> system parameter, and an additional list of -directories that is the value of the <code>GS_FONTPATH</code> environment -variable (or the value provided with the <code>-sFONTPATH=</code> switch, -if present).</p> - -<p> -At startup time, Ghostscript reads in the <code>Fontmap</code> files in -every directory on the search path (or in the list provided with the -<code>-sFONTMAP=</code> switch, if present): these files are catalogs of -fonts and the files that contain them. (See <a href="Fonts.htm#Fontmap">the -documentation of fonts</a> for details.) Then, when Ghostscript needs to -find a font that isn't already loaded into memory, it goes through a series -of steps.</p> - -<ul> - -<li> -First, it looks up the font name in the combined Fontmaps. If there is an -entry for the desired font name, and the file named in the entry can be -found in some directory on the general search path (defined by -<code>-I</code>, <code>GS_LIB</code>, and -<code>GS_LIB_DEFAULT</code>), and the file is loaded successfully, and -loading it defines a font of the desired name, that is the end of the -process.</li> - -<li> -If this process fails at any step, Ghostscript looks for a file whose name -is the concatenation of the value of the <code>FontResourceDir</code> -system parameter and the font name, with no extension. If such a file -exists, can be loaded, and defines a font of the desired name, that again is -the end. The value of <code>FontResourceDir</code> is normally the -string <code>/Resource/Font/</code>, but it can be changed with the -<code>setsystemparams</code> operator: see the PostScript Language -Reference Manual for details.</li> - -<li> -If that fails, Ghostscript then looks for a file on the general search path -whose name is the desired font name, with no extension. If such a file -exists, can be loaded, and defines a font of the desired name, that again is -the end.</li> - -<li> -If that too fails, Ghostscript looks at the <code>GS_FONTPATH</code> -environment variable (or the value provided with the -<code>-sFONTPATH=</code> switch, if present), which is also a list of -directories. It goes to the first directory on the list, and it's descendants, -looking for all files that appear to contain PostScript fonts (also Truetype -fonts); it then adds all those files and fonts to the combined Fontmaps, and -starts over.</li> - -<li> -If scanning the first FONTPATH directory doesn't produce a file that -provides the desired font, it adds the next directory on the FONTPATH list, -and so on until either the font is defined successfully or the list is -exhausted.</li> - -<li> -Finally, if all else fails, it will try to find a substitute for the font -from among the standard 35 fonts.</li> - -</ul> - -<p> -<a href="#CIDFonts">CID fonts</a> (e.g. Chinese, Japanese and Korean) -are found using a different method.</p> - -<blockquote><table> -<tr><th colspan="2">Differences between search path and font path</th></tr> -<tr><th>Search path</th> - - <th>Font path</th></tr> -<tr><td><code>-I</code> switch</td> - - <td><code>-sFONTPATH=</code> switch</td></tr> -<tr><td><code>GS_LIB</code> and <code>GS_LIB_DEFAULT</code> - environment variables</td> - - <td><code>GS_FONTPATH</code> environment variable</td></tr> -<tr><td valign="top">Consulted first</td> - - <td valign="top">Consulted only if search path and - <code>FontResourceDir</code> don't provide the file.</td></tr> -<tr><td valign="top">Font-name-to-file-name mapping given in Fontmap - files; aliases are possible, and there need not be any relation - between the font name in the Fontmap and the - <code>FontName</code> in the file.</td> - <td valign="top">Font-name-to-file-name mapping is - implicit – the <code>FontName</code> in the file is - used. Aliases are not possible.</td></tr> -<tr><td valign="top">Only fonts and files named in Fontmap are used.</td> - - <td valign="top">Every Type 1 font file in each directory is - available; if TrueType fonts are supported (the - <code>ttfont.dev</code> feature was included when the - executable was built), they are also available.</td></tr> -</table></blockquote> - -<p> -If you are using one of the following types of computer, you may wish to -set the environment variable <code>GS_FONTPATH</code> to -the value indicated so that Ghostscript will automatically acquire all the -installed Type 1 (and, if supported, TrueType) fonts (but see below for -notes on systems marked with "*"):</p> - -<blockquote><table> -<tr><th colspan="3">Suggested GS_FONTPATH for different systems</th></tr> -<tr><th> </th> - - <th align="left">System type</th> - - <th valign="bottom" align="left">GS_FONTPATH</th></tr> -<tr><td> </td> - - <td valign="top">Digital Unix</td> - - <td><code>/usr/lib/X11/fonts/Type1Adobe</code></td></tr> -<tr><td> </td> - - <td valign="top">Ultrix</td> - - <td><code>/usr/lib/DPS/outline/decwin</code></td></tr> -<tr><td> </td> - - <td valign="top">HP-UX 9</td> - - <td><code>/usr/lib/X11/fonts/type1.st/typefaces</code></td></tr> -<tr><td> </td> - - <td valign="top">IBM AIX</td> - - <td><code>/usr/lpp/DPS/fonts/outlines - <br>/usr/lpp/X11/lib/X11/fonts/Type1 - <br>/usr/lpp/X11/lib/X11/fonts/Type1/DPS</code></td></tr> -<tr><td> </td> - - <td valign="top">NeXT</td> - - <td><code>/NextLibrary/Fonts/outline</code></td></tr> -<tr><td>*</td> - - <td valign="top">SGI IRIX</td> - - <td><code>/usr/lib/DPS/outline/base - <br>/usr/lib/X11/fonts/Type1</code></td></tr> -<tr><td> </td> - - <td valign="top">SunOS 4.x<br>(NeWSprint only)</td> - - <td valign="top"><code>newsprint_2.5/SUNWsteNP/reloc/$BASEDIR/NeWSprint/<br> small_openwin/lib/fonts</code></td></tr> -<tr><td>**</td> - - <td valign="top">SunOS 4.x</td> - - <td><code>/usr/openwin/lib/X11/fonts/Type1/outline</code></td></tr> -<tr><td>**</td> - - <td valign="top">Solaris 2.x</td> - - <td><code>/usr/openwin/lib/X11/fonts/Type1/outline</code></td></tr> -<tr><td> </td> - - <td valign="top">VMS</td> - - <td><code>SYS$COMMON:[SYSFONT.XDPS.OUTLINE]</code></td></tr> -</table> - -<p> -<b>*</b> On SGI IRIX systems, you must use <code>Fontmap.SGI</code> in -place of <code>Fontmap</code> or <code>Fontmap.GS</code>, because -otherwise the entries in <code>Fontmap</code> will take precedence over -the fonts in the FONTPATH directories.</p> - -<p> -<b>**</b> On Solaris systems simply setting <code>GS_FONTPATH</code> or -using <code>-sFONTPATH=</code> may not work, because for some reason some -versions of Ghostscript can't seem to find any of the Type1 fonts in -<code>/usr/openwin/lib/X11/fonts/Type1/outline</code>. (It says: "15 -files, 15 scanned, 0 new fonts". We think this problem has been fixed in -Ghostscript version 6.0, but we aren't sure because we've never been able to -reproduce it.) See <code>Fontmap.Sol</code> instead. Also, on Solaris -2.x it's probably not worth your while to add Sun's fonts to your font path -and Fontmap. The fonts Sun distributes on Solaris 2.x in the directories</p> - -<blockquote><code> - /usr/openwin/lib/X11/fonts/Type1<br> - /usr/openwin/lib/X11/fonts/Type1/outline -</code></blockquote> - -<p> -are already represented among the ones distributed as part of Ghostscript; -and on some test files, Sun's fonts have been shown to cause incorrect -displays with Ghostscript.</p> - -</blockquote> - -<p> -These paths may not be exactly right for your installation; if the indicated -directory doesn't contain files whose names are familiar font names like -Courier and Helvetica, you may wish to ask your system administrator where -to find these fonts.</p> - -<p> -Adobe Acrobat comes with a set of fourteen Type 1 fonts, on Unix typically -in a directory called ...<code>/Acrobat3/Fonts</code>. There is no -particular reason to use these instead of the corresponding fonts in the -Ghostscript distribution (which are of just as good quality), except to save -about a megabyte of disk space, but the installation documentation explains -how to do it <a href="Install.htm#Use_Acrobat_fonts_Unix">on Unix</a>.</p> - -<h3><a name="CIDFonts"></a>CID fonts</h3> - -<p> -CID fonts are PostScript resources containing a -large number of glyphs (e.g. glyphs for Far East languages, -Chinese, Japanese and Korean). -Please refer to the PostScript Language Reference, -third edition, for details.</p> - -<p> -CID font resources are a different kind of PostScript resource from fonts. -In particular, they cannot be used as regular fonts. -CID font resources must first be combined with a CMap resource, which -defines specific codes for glyphs, before it can be used as a font. This -allows the reuse of a collection of glyphs with different encodings.</p> - -<p> -The simplest method to request a font composed of a CID font resource -and a CMap resource in a PostScript document is -<blockquote><code> -/CIDFont-CMap findfont -</code></blockquote> -where <code>CIDFont</code> is a name of any -CID font resource, and <code>CMap</code> is a name of a CMap resource -designed for the same character collection. The interpreter will compose -the font automatically from the specified CID font and CMap resources. -Another method is possible using the <code>composefont</code> operator.</p> - -<p> -CID fonts must be placed in the <code>/Resource/CIDFont/</code> directory. -They are not found using <a href="#Font_lookup">Font lookup</a> -on the search path or font path.</p> - -<h3><a name="CIDFontSubstitution"></a>CID font substitution</h3> -<h4><a name="AutomaticCIDFontSubstitution"></a>Automatic CIDFont Substitution</h4> -<p> -In general, it is highly recommended that CIDFonts used in the creation of PDF -jobs should be embedded or available to Ghostscript as CIDFont resources, this -ensures that the character set, and typeface style are as intended by the -author.</p> -<p> -In cases where the original CIDFont is not available, the next best option is -to provide Ghostscript with a mapping to a suitable alternative CIDFont - see -below for details on how this is achieved. However, Ghostscript does provide the -ability to use a "fall back" CIDFont substitute. As shipped, this uses the -DroidSansFallback.ttf font. This font contains a large number of glyphs covering -several languages, but it is not comprehensive. There is, therefore, a chance -that glyphs may be wrong, or missing in the output when this fallback is used.</p> -<p> -Internally, the font is referenced as CIDFont resource called <code>CIDFallBack</code>, thus -a different fallback from DroidSansFallback.ttf can be specified adding a -mapping to your cidfmap file (see below for details) to map the name "CIDFallBack" -as you prefer. For <code>CIDFallBack</code> the mapping <bold>must</bold> be a TrueType -font or TrueType collection, it cannot be a Postscript CIDFont file.</p> -<p> -As with any font containing large numbers of glyphs, DroidSansFallback.ttf is -quite large (~3.5Mb at the of writing). If this is space you cannot afford in -your use of Ghostscript, you can simply delete the file from: -<code>Resource/CIDFSubst/DroidSansFallback.ttf</code>. The build system will cope with the -file being removed, and the initialization code will avoid adding the internal -fall back mapping if the file is missing.</p> -<p> -If DroidSansFallback.ttf is removed, and no other <code>CIDFallBack</code> mapping is supplied, -the final "fall back" is to use a "dumb" bullet CIDFont, called <code>ArtifexBullet</code>. As -the name suggests, this will result in all the glyphs from a missing CIDFont being replaced with -a simple bullet point.</p> -<p> -This type of generic fall back CIDFont substitution can be very useful for -viewing and proofing jobs, but may not be appropriate for a "production" -workflow, where it is expected that <b>only</b> the original font should be -used. For this situation, you can supply Ghostscript with the command line option: -<code>-dPDFNOCIDFALLBACK</code>. By combining <code>-dPDFNOCIDFALLBACK</code> with <code>-dPDFSTOPONERROR</code> -a production workflow can force a PDF with missing CIDFonts to error, and avoid -realising a CIDFont was missing only after printing.</p> -<p> -The directory in which the fallback TrueType font or collection can be specified by the -command line parameter <code>-sCIDFSubstPath="path/to/TTF"</code>, or with the environment -variable <code>CIDFSUBSTPATH</code>. The file name of the substitute TrueType font can be -specified using the command line parameter <code>-sCIDFSubstFont="TTF file name"</code> or -the environment variable <code>CIDFSUBSTFONT</code>.</p> - -<h4><a name="ExplicitCIDFontSubstitution"></a>Explicit CIDFont Substitution</h4> -<p>Substitution of CID font resources is controlled, by default, by the Ghostscript -configuration file <code>Resource/Init/cidfmap</code>, which defines a CID font resource map.</p> -<p> -The file forms a table of records, each of which should use one of three formats, -explained below. Users may modify <code>Resource/Init/cidfmap</code> to configure -Ghostscript for a specific need. Note that the default Ghostscript build includes -such configuration and resource files in a rom file system built into the executable. -So, to ensure your changes have an effect, you should do one of the following: rebuild -the executable; use the "-I" command line option to add the directory containing your -modified file to Ghostscript's search path; or, finally, build Ghostscript to use disk -based resources.</p> - -<h4>Format 1</h4> -<p> To substitute a CID font resource with another CID font resource, add a record like this :</p> - -<blockquote><code> -/Substituted /Original ; -</code></blockquote> -<p>where <code>Substituted</code> is a name of CID font resource being used -by a document, and <code>Original</code> is a name of an available -CID font resource. Please pay attention that both them must be -designed for same character collection. In other words, you -cannot substitute a Japanese CID font resource with a Korean CID font resource, -etc. CMap resource names must not appear in -<code>lib/cidfmap</code>. The trailing semicolon and the space before it -are both required.</p> - -<h4>Format 2</h4> -<p>To substitute (emulate) a CID font resource with a TrueType font file, add a record like this :</p> - -<blockquote><code> -/Substituted << keys&values >> ; -</code></blockquote> - -<p>Where <code>keys&values</code> are explained in the table below.</p> - -<table> - -<tr valign="top"> <th>Key</th> - <th>Type</th> - <th>Description</th></tr> -<tr valign="top"> <td><code>/Path</code></td> - <td>string</td> - <td>A path to a TrueType font file. This must be an absolute path. - If using <code><a href="#Safer">-dSAFER</a></code>, the directory - containing the font file must be on one of the permitted paths.</td></tr> -<tr valign="top"> <td><code>/FileType</code></td> - <td>name</td> - <td>Must be <code>/TrueType</code>.</td></tr> -<tr valign="top"> <td><code>/SubfontID</code></td> - <td>integer</td> - <td>(optional) Index of the font in font collection, such as TTC. - This is ignored if <code>Path</code> doesn't specify a collection. - The first font in a collection is 0. - Default value is 0.</td></tr> -<tr valign="top"> <td><code>/CSI</code> - <td>array of 2 or 3 elements - <td>(required) Information for building <code>CIDSystemInfo</code>. - <p> - If the array consists of 2 elements, - the first element is a string, which specifies <code>Ordering</code>; - the second element is a number, which specifies <code>Supplement</code>. - <p> - If the array consists of 3 elements, - the first element is a string, which specifies <code>Registry</code>; - the second element is a string, which specifies <code>Ordering</code>; - the third element is a number, which specifies <code>Supplement</code>. -</table> - -<p> -Currently only CIDFontType 2 can be emulated with a TrueType font. -The TrueType font must contain enough characters to cover an -Adobe character collection, which is specified in <code>Ordering</code> and used in documents.</p> - -<h4>Format 3</h4> -<p> To point Ghostscript at a specific CIDFont file outside it's "normal" resource search path :</p> - -<blockquote><code> -/CIDName (path/to/cid/font/file) ; -</code></blockquote> -<p>where <code>CIDName</code> is a name of CID font resource being used -by a document, and <code>"path/to/cid/font/file"</code> is the path to the -Postscript CIDFont file, including the file name. NOTE: the CIDFont file, when -executed by the Postscript interpreter, must result in a CIDFont resource being -defined whose CIDFontName matches the "CIDName" key for the current record. -I.E. an entry with the key /PingHei-Bold must reference a file which creates a -CIDFont resource called "PingHei-Bold". To substitute a file based CIDFont for -a differently named CIDFont, use formats 1 and 3 in combination (the order of the -entries is not important).</p> - -<p>The trailing semicolon and the space before it are both required.</p> - -<p> -Examples :</p> - - -<blockquote><code> -<h5>Format 1:</h5> -/Ryumin-Medium /ShinGo-Bold ;<br> -/Ryumin-Light /MS-Mincho ;<br> -<h5>Format 2:</h5> -/Batang << /FileType /TrueType /Path (C:/WINDOWS/fonts/batang.ttc) /SubfontID 0 /CSI [(Korea1) 3] >> ;<br> -/Gulim << /FileType /TrueType /Path (C:/WINDOWS/fonts/gulim.ttc) /SubfontID 0 /CSI [(Korea1) 3] >> ;<br> -/Dotum << /FileType /TrueType /Path (C:/WINDOWS/fonts/gulim.ttc) /SubfontID 2 /CSI [(Korea1) 3] >> ;<br> -<br> -<h5>Format 1 & 2</h5> -/SimSun << /FileType /TrueType /Path (C:/WINDOWS/fonts/simsun.ttc) /SubfontID 0 /CSI [(GB1) 2] >> ;<br> -/SimHei << /FileType /TrueType /Path (C:/WINDOWS/fonts/simhei.ttf) /SubfontID 0 /CSI [(GB1) 2] >> ;<br> -/STSong-Light /SimSun ;<br> -/STHeiti-Regular /SimHei ;<br> -<h5>Format 3:</h5> -/PMingLiU (/usr/local/share/font/cidfont/PMingLiU.cid) ;<br> -<h5>Format 1 & 3</h5> -/Ryumin-Light /PMingLiU ;<br> -/PMingLiU (/usr/local/share/font/cidfont/PMingLiU.cid) ;<br> -</code></blockquote> - -<p>The win32 installer of recent version of ghostscript has a checkbox for -"Use Windows TrueType fonts for Chinese, Japanese and Korean" to optionally update -lib/cidfmap with the common CJK fonts provided by Microsoft products. The script -can also be run separately (e.g. against a network drive with windows CJK fonts):</p> - -<blockquote><code> -gswin32c -q -dBATCH -sFONTDIR=c:/windows/fonts -sCIDFMAP=lib/cidfmap lib/mkcidfm.ps -</code></blockquote> - -<p> -Note that the font file path uses Postscript syntax. -Because of this, backslashes in the paths must be -represented as a double backslash.</p> - -<p> -This can complicate substitutions for fonts with non-Roman names. -For example, if a PDF file asks for a font with the name -<code>/#82l#82r#83S#83V#83b#83N</code>. This cannot be used directly -in a cidfmap file because the #xx notation in names is a PDF-only -encoding. Instead, try something like:</p> -<blockquote> -<code><82C68272835383568362834E>cvn << /Path -(C:/WINDOWS/Fonts/msmincho.ttc) /FileType /TrueType /SubfontID 0 /CSI -[(Japan1) 3] >> ;</code> -</blockquote> -<p>Where <code><82C68272835383568362834E></code> is the same byte -sequence converted to a hex string. This lets you specify a name -using any sequence of bytes through the encodings available for -Postscript strings.</p> - -<p> -Note that loading truetype fonts directly from -<code>/Resources/CIDFont</code> is no longer supported. -There is no reliable way to generate a character ordering for truetype -fonts. The 7.0x versions of Ghostscript supported this by assuming a Japanese -character ordering. This is replaced in the 8.0x and later releases with -the more general <code>cidfmap</code> mechanism.</p> - -<p> -The PDF specification requires CID font files to be embedded, -however some documents omit them. As a workaround -the PDF interpreter applies an additional substitution method when -a requested CID font resource is not embedded and it is not available. -It takes values of the keys <code>Registry</code> and <code>Ordering</code> -from the <code>CIDFontSystem</code> dictionary, -and concatenates them with a dash inserted. -For example, if a PDF CID font resource specifies -<blockquote><code> -/CIDSystemInfo << /Registry (Adobe) /Ordering (CNS1) /Supplement 1 >> -</code></blockquote> -the generated subsitituite name is <code>Adobe-CNS1</code>. -The latter may look some confusing for a font name, -but we keep it for compatibility with older Ghostscript versions, -which do so due to a historical reason. -Add a proper record to <code>lib/cidfmap</code> to provide it.</p> - -<p> -Please note that when a PDF font resource specifies -<blockquote><code> -/Registry (Adobe) /Ordering (Identity) -</code></blockquote> -there is no way to determine the language properly. -If the CID font file is not embedded, the <code>Adobe-Identity</code> -record depends on the document and a correct record isn't possible when -a document refers to multiple Far East languages. -In the latter case add individual records for specific CID font names used in the document.</p> - -<p> -Consequently, if you want to handle any PDF document with -non-embedded CID fonts (which isn't a correct PDF), -you need to create a suitable <code>lib/cidfmap</code> by hand, -possibly a specific one for each document.</p> - -<h3><a name="UnicodeTT"></a>Using Unicode True Type fonts</h3> - -<p>Ghostscript can make use of Truetype fonts with a Unicode character set. -To do so, you should generate a (<b>NOTE:</b> non-standard!) Postscript or PDF -job where the relevant text is encoded as UTF-16. Ghostscript may be used for -converting such jobs to other formats (Postscript, PDF, PXL etc). -The resulting output will be compliant with the spec (unlike the input).</p> - -<p> -To render an UTF-16 encoded text, one must do the following :</p> - -<ul> - -<li> -Provide a True Type font with Unicode Encoding. -It must have a <code>cmap</code> table with -<code>platformID</code> equals to 3 (Windows), -and <code>SpecificID</code> eqials to 1 (Unicode).</li> - -<li> -Describe the font in <code>Resource/Init/cidfmap</code> -with special values for the <code>CSI</code> key : -<code>[(Artifex) (Unicode) 0]</code>.</li> - -<li> -In the PS or PDF job combine the font -with one of CMap <code>Identity-UTF16-H</code> -(for the horizontal writing mode) -or <code>Identity-UTF16-V</code> -(for the vertical writing mode). -Those CMaps are distributed with Ghostscript -in <code>Resource/CMap</code>.</li> - -</ul> - -<p>Please note that <code>/Registry (Adobe) /Ordering (Identity)</code> -won't properly work for Unicode documents, -especially for the searchability feature -(see <a href="#CIDFontSubstitution">CID font substitution</a>).</p> - -<h3><a name="Temp_files"></a>Temporary files</h3> - -<blockquote><table> -<tr><th colspan="3">Where Ghostscript puts temporary files</th></tr> -<tr> - <th align="left">Platform</th> - - <th align="left">Filename</th> - - <th align="left">Location</th></tr> -<tr valign="top"> <td>MS Windows and OpenVMS</td> - - <td><code>_temp_</code>XX.XXX</td> - - <td>Current directory</td></tr> -<tr valign="top"> <td>OS/2</td> - - <td><code>gs</code>XXXXXX</td> - - <td>Current directory</td></tr> -<tr valign="top"> <td>Unix</td> - - <td><code>gs_</code>XXXXX</td> - - <td><code>/tmp</code></td></tr> -</table></blockquote> - -<p> -You can change in which directory Ghostscript creates temporary files by -setting the <code>TMPDIR</code> or <code>TEMP</code> environment -variable to the name of the directory you want used. Ghostscript currently -doesn't do a very good job of deleting temporary files if it exits because -of an error; you may have to delete them manually from time to time.</p> - - -<hr> - -<h2><a name="Platforms"></a>Notes on specific platforms</h2> - -<h3><a name="Word size"></a>Word size (32 or 64 bits)</h3> - -<p> -The original PostScript language specification, while not stating a specific word sise, -defines 'typical' limits which make it clear that it was intended to run as a 32-bit -environment. Ghostscript was originally coded that way, and the heritage remains -within the code base. -</p> -<p> -Because the Ghostscript PDF interpreter is currently written in PostScript, it proved -necessary to add support for 64-bit integers so that we could process PDF files which -exceed 2GB in size. This is the only real purpose in adding support for large integers, -however since that time, we have made some efforts to allow for the use of 64-bit words; in -particular the use of integers, but also lifting the 64K limit on strings and arrays, -among other areas. -</p> -However this is, obviously, dependent on the operating system and compiler support -available. Not all builds of Ghostscript will support 64-bit integers, though some -32-bit builds (eg Windows) will. -<p> -Even when the build supports 64-bit words, you should be aware that there are areas -of Ghostscript which do not support 64-bit values. Sometimes these are dependent -on the build and other times they are inherent in the architecture of Ghostscript (the graphics library does not -support 64-bit co-ordinates in device space for example, and most likely never will). -</p> -<p> -Note that the extended support for 64-bit word size can be disabled by executing 'true .setcpsimode', -This is important for checking the output of the Quality Logic test suite (and possibly other -test suites) as the tests make assumptions about the sizes of integers (amongst other things). -You can run /ghostpdl/Resource/Init/gs_cet.ps to change Ghostscript's behaviour so -that it matches the observed behaviour of Adobe CPSI interpreters. -</p> - -<h3><a name="Unix"></a>Unix</h3> - -<p> -The Ghostscript distribution includes some Unix shell scripts to use with -Ghostscript in different environments. These are all user-contributed -code, so if you have questions, please contact the user identified in the -file, not Artifex Software.</p> - -<dl> - <dt><code>pv.sh</code></dt> - <dd>Preview a specified page of a <code>dvi</code> file in an X window</dd> -</dl> - -<dl> - <dt><code>sysvlp.sh</code></dt> - <dd>System V 3.2 lp interface for parallel printer</dd> -</dl> - -<dl> - <dt><code>pj-gs.sh</code></dt> - <dd>Printing on an H-P PaintJet under HP-UX</dd> -</dl> - -<dl> - <dt><code>unix-lpr.sh</code></dt> - <dd>Queue filter for <code>lpr</code> under Unix; - <a href="Unix-lpr.htm">its documentation</a> is intended for system - administrators</dd> -</dl> - -<dl> - <dt><code>lprsetup.sh</code></dt> - <dd>Setup for <code>unix-lpr.sh</code></dd> -</dl> - -<h3><a name="VMS"></a>VMS</h3> - -<ul> -<li>To be able to specify switches and file names when invoking the - interpreter, define <code>gs</code> as a foreign command:</li> - -<li> -<blockquote> -<code>$ gs == "$</code><em>disk</em><code>:[</code><em>directory</em><code>]gs.exe</code>" -</blockquote> -</li> - -<li> -<p> -where the "<em>disk</em>" and "<em>directory</em>" specify where - the Ghostscript executable is located. For instance,</p> -</li> -<li> -<blockquote><code> -$ gs == "$dua1:[ghostscript]gs.exe" -</code></blockquote> -</li> - -<li>On VMS systems, the last character of each "directory" name indicates -what sort of entity the "directory" refers to. If the "directory" name -ends with a colon "<code>:</code>", it is taken to refer to a logical -device, for instance</li> - -<li> -<blockquote><code> -$ define ghostscript_device dua1:[ghostscript_510]<br> -$ define gs_lib ghostscript_device: -</code></blockquote> -</li> - -<li> -<p> -If the "directory" name ends with a closing square bracket -"<code>]</code>", it is taken to refer to a real directory, for instance</p> -</li> -<li> -<blockquote><code> -$ define gs_lib dua1:[ghostscript] -</code></blockquote> -</li> -<li>Defining the logical <code>GS_LIB</code></li> -<li> -<blockquote> -<code>$ define gs_lib</code> <em>disk</em><code>:[</code><em>directory</em><code>]</code> -</blockquote> -</li> -<li> -<p> -allows Ghostscript to find its initialization files in the Ghostscript -directory even if that's not where the executable resides.</p> -</li> - -<li>Although VMS DCL itself converts unquoted parameters to upper case, C -programs such as Ghostscript receive their parameters through the C runtime -library, which forces all unquoted command-line parameters to lower case. -That is, with the command</li> - -<li> -<blockquote><code> -$ gs -Isys$login: -</code></blockquote> -</li> - -<li> -<p> -Ghostscript sees the switch as <code>-isys$login</code>, -which doesn't work. To preserve the case of switches, quote them like -this:</p> -</li> - -<li> -<blockquote><code> -$ gs "-Isys$login:" -</code></blockquote> -</li> - -<li>If you write printer output to a file with -<code>-sOutputFile=</code> and then want to print the file later, use -"<code>PRINT/PASSALL</code>".</li> -</ul> - -<ul> -<li>PDF files (or PostScript files that use the -<code>setfileposition</code> operator) must be "stream LF" type files to -work properly on VMS systems. (<b><em>Note:</em></b> This definitely matters -if Ghostscript was compiled with DEC C; we are not sure of the situation if -you use <code>gcc</code>.) Because of this, if you transfer files by -FTP, you probably need to do one of these two things after the transfer:</li> - -<li> - <ol> - <li>If the FTP transfer was in text (ASCII) mode:</li> - - <li> - <blockquote> - <code>$ convert/fdl=streamlf.fdl</code> input-file output-file - </blockquote> - - - <p> - where the contents of the file <code>STREAMLF.FDL</code> are</p> - - <blockquote> - <pre>FILE - ORGANIZATION sequential - - RECORD - BLOCK_SPAN yes - CARRIAGE_CONTROL carriage_return - FORMAT stream_lf - </pre></blockquote> - </li> - - <li>If the FTP transfer was in binary mode:</li> - - <li> - <blockquote><code> - $ set file/attribute=(rfm:stmlf) - </code></blockquote> - </li> - </ol> -</li> -</ul> - -<h4><a name="VMS_X_Windows"></a>Using X Windows on VMS</h4> - -<p> -If you are using on an X Windows display, you can set it up with the node -name and network transport, for instance</p> - -<blockquote><code> - $ set display/create/node="doof.city.com"/transport=tcpip -</code></blockquote> - -<p> -and then run Ghostscript by typing <code>gs</code> at the command line.</p> - -<h3><a name="MS_Windows"></a>MS Windows</h3> - -<p> -The name of the Ghostscript command line executable on MS Windows is -<code>gswin32c</code>/<code>gswin64c</code> so use this instead of the -plain '<code>gs</code>' in the quickstart examples.</p> - -<p> -To run the batch files in the ghostscript <code>lib</code> directory, -you must add <em>gs\</em><code>bin</code> and -<em>gs\</em><code>lib</code> to the <code>PATH</code>, where -<em>gs</em> is the top-level Ghostscript directory.</p> - -<p> -When passing options to ghostcript through a batch file wrapper such as -<code>ps2pdf.bat</code> you need to substitute '#' for '=' as the separator -between options and their arguments. For example:</p> -<blockquote><pre> -ps2pdf -sPAPERSIZE#a4 file.ps file.pdf -</pre></blockquote> - -<p>Ghostscript treats '#' the same internally, and the '=' is mangled by -the command shell.</p> - -<p> -There is also an older version for MS Windows called just <code>gswin32</code> -that provides its own window for the interactive postscript prompt. -The executable <code>gswin32c</code>/<code>gswin64c</code> is usually the better -option since it uses the native command prompt window.</p> - -<p> -For printer devices, the default output is the default printer. -This can be modified as follows.</p> - -<blockquote> -<dl> - <dt><code>-sOutputFile="%printer%printer name"</code></dt> - <dd>Output to the named printer. If your printer is named "HP DeskJet 500" - then you would use <code>-sOutputFile="%printer%HP DeskJet 500"</code>.</dd> - -</dl> -</blockquote> - -<h3><a name="MS-DOS"></a>MS-DOS</h3> - -<p> -<strong>Note:</strong> Ghostscript is no longer supported on MS-DOS.</p> - -<p> -Invoking Ghostscript from the command prompt in Windows is supported by -the Windows executable described above.</p> - -<h3><a name="X_Windows"></a>X Windows</h3> - -<p> -Ghostscript looks for the following resources under the program name -<code>ghostscript</code> and class name -<code>Ghostscript</code>; the ones marked "**" are -calculated from display metrics:</p> - -<blockquote><table> -<tr><th colspan="3">X Windows resources</th></tr> -<tr><th align="left">Name</th> - - <th align="left">Class</th> - - <th align="left">Default</th></tr> -<tr><td><code>background</code></td> - - <td><code>Background</code></td> - - <td><code>white</code></td></tr> -<tr><td><code>foreground</code></td> - - <td><code>Foreground</code></td> - - <td><code>black</code></td></tr> -<tr><td><code>borderColor</code></td> - - <td><code>BorderColor</code></td> - - <td><code>black</code></td></tr> -<tr><td><code>borderWidth</code></td> - - <td><code>BorderWidth</code></td> - - <td><code>1</code></td></tr> -<tr><td><code>geometry</code></td> - - <td><code>Geometry</code></td> - - <td><code>NULL</code></td></tr> -<tr><td><code>xResolution</code></td> - - <td><code>Resolution</code></td> - - <td>**</td></tr> -<tr><td><code>yResolution</code></td> - - <td><code>Resolution</code></td> - - <td>**</td></tr> -<tr><td><code>useExternalFonts</code></td> - - <td><code>UseExternalFonts</code></td> - - <td><code>true</code></td></tr> -<tr><td><code>useScalableFonts</code></td> - - <td><code>UseScalableFonts</code></td> - - <td><code>true</code></td></tr> -<tr><td><code>logExternalFonts</code></td> - - <td><code>LogExternalFonts</code></td> - - <td><code>false</code></td></tr> -<tr><td><code>externalFontTolerance</code></td> - - <td><code>ExternalFontTolerance</code></td> - - <td><code>10.0</code></td></tr> -<tr><td><code>palette</code></td> - - <td><code>Palette</code></td> - - <td><code>Color</code></td></tr> -<tr><td><code>maxGrayRamp</code></td> - - <td><code>MaxGrayRamp</code></td> - - <td><code>128</code></td></tr> -<tr><td><code>maxRGBRamp</code></td> - - <td><code>MaxRGBRamp</code></td> - - <td><code>5</code></td></tr> -<tr> <td><code>maxDynamicColors</code></td> - - <td><code>MaxDynamicColors</code></td> - - <td><code>256</code></td></tr> -<tr><td><code>useBackingPixmap</code></td> - - <td><code>UseBackingPixmap</code></td> - - <td><code>true</code></td></tr> -<tr><td><code>useXPutImage</code></td> - - <td><code>UseXPutImage</code></td> - - <td><code>true</code></td></tr> -<tr><td><code>useXSetTile</code></td> - - <td><code>UseXSetTile</code></td> - - <td><code>true</code></td></tr> -</table></blockquote> - -<h4><a name="X_resources"></a>X resources</h4> - -<ul> -<li> -To set X resources, put them in a file (such as -<code>~/.Xdefaults</code> on Unix) in a form like this:</li> - -<li> -<blockquote><table> - <tr><td><code>Ghostscript*geometry:</code></td><td><code>595x842-0+0</code></td></tr> - <tr><td><code>Ghostscript*xResolution:</code></td><td><code>72</code></td></tr> - <tr><td><code>Ghostscript*yResolution:</code></td><td><code>72</code></td></tr> -</table></blockquote> - -<p> - Then merge these resources into the X server's resource database:</p> - -<blockquote><code> - xrdb -merge ~/.Xdefaults -</code></blockquote> - -</li> - -<li> -Ghostscript doesn't look at the default system background and foreground -colors; if you want to change the background or foreground color, you must -set them explicitly for Ghostscript. This is a deliberate choice, so that -PostScript documents will display correctly by default -- with white as -white and black as black -- even if text windows use other colors.</li> - -<li> -The <code>geometry</code> resource affects only window placement.</li> - -<li> -Resolution is expressed in pixels per inch (1 inch = 25.4mm).</li> - -<li> -The font tolerance gives the largest acceptable difference in height of the -screen font, expressed as a percentage of the height of the desired font.</li> - -<li> -The <code>palette</code> resource can be used to restrict Ghostscript to -using a grayscale or monochrome palette.</li> - -<li> -<code>maxRGBRamp</code> and -<code>maxGrayRamp</code> control the maximum number of -colors that ghostscript allocates ahead of time for the dither cube (ramp). -Ghostscript never preallocates more than half the cells in a colormap. -<code>maxDynamicColors</code> controls the maximum -number of colors that Ghostscript will allocate dynamically in the -colormap.</li> -</ul> - -<h4><a name="X_server_bugs"></a>Working around bugs in X servers</h4> - -<p> -The "<code>use</code>..." resources exist primarily to work around bugs - in X servers.</p> - -<ul> -<li> Old versions of DEC's X server (DECwindows) have bugs that - require setting <code>useXPutImage</code> or - <code>useXSetTile</code> to - <code>false</code>.</li> - -<li> Some servers do not implement backing pixmaps properly, or do not - have enough memory for them. If you get strange behavior or "out - of memory" messages, try setting - <code>useBackingPixmap</code> to - <code>false</code>.</li> - -<li> Some servers do not implement tiling properly. This appears - as broad bands of color where dither patterns should appear. If - this happens, try setting - <code>useXSetTile</code> to - <code>false</code>.</li> - -<li> Some servers do not implement bitmap or pixmap displaying properly. - This may appear as white or black rectangles where characters - should appear; or characters may appear in "inverse video" (for - instance, white on a black rectangle rather than black on white). - If this happens, try setting - <code>useXPutImage</code> to - <code>false</code>.</li> -</ul> - -<h4><a name="X_device_parameters"></a>X device parameters</h4> - -<p> -In addition to the device parameters recognized by <a -href="Language.htm#Device_parameters">all devices</a>, Ghostscript's X -driver provides parameters to adjust its performance. Users will rarely -need to modify these. Note that these are parameters to be set with the -<code>-d</code> switch in the command line (e.g., -<code>-dMaxBitmap=10000000</code>), not resources to be defined in the -<code>~/.Xdefaults</code> file.</p> - -<dl> - <dt><code>AlwaysUpdate <boolean></code></dt> -<dd>If <code>true</code>, the driver updates the screen after each -primitive drawing operation; if <code>false</code> (the default), the - driver uses an intelligent buffered updating algorithm.</dd> -</dl> - -<dl> - <dt><code>MaxBitmap <integer></code></dt> -<dd>If the amount of memory required to hold the pixmap for the window is no -more than the value of <code>MaxBitmap</code>, the driver will draw to a -pixmap in Ghostscript's address space (called a "client-side pixmap") and -will copy it to the screen from time to time; if the amount of memory -required for the pixmap exceeds the value of <code>MaxBitmap</code>, the -driver will draw to a server pixmap. Using a client-side pixmap usually -provides better performance -- for bitmap images, possibly much better -performance -- but since it may require quite a lot of RAM (e.g., about 2.2 -Mb for a 24-bit 1024x768 window), the default value of - <code>MaxBitmap</code> is 0.</dd> -</dl> - -<dl> - <dt><code>MaxTempPixmap, MaxTempImage <integer></code></dt> -<dd>These control various aspects of the driver's buffering behavior. For - details, please consult the source file <code>gdevx.h</code>.</dd> -</dl> - -<h3><a name="SCO_Unix"></a>SCO Unix</h3> - -<p> -Because of bugs in the SCO Unix kernel, Ghostscript will not work if you -select direct screen output and also allow it to write messages on the -console. If you are using direct screen output, redirect Ghostscript's - terminal output to a file.</p> - -<hr> - -<h2><a name="Options"></a>Command line options</h2> - -<p> -Unless otherwise noted, these switches can be used on all platforms.</p> - -<h3><a name="General_switches"></a>General switches</h3> - -<h4><a name="Input_control"></a>Input control</h4> - -<dl> - <dt><code>@</code><em>filename</em></dt> -<dd>Causes Ghostscript to read <em>filename</em> and treat its contents the -same as the command line. (This was intended primarily for getting around -DOS's 128-character limit on the length of a command line.) Switches or -file names in the file may be separated by any amount of white space - (space, tab, line break); there is no limit on the size of the file.</dd> -</dl> - -<dl> - <dt><code>--</code> <em>filename arg1 ...</em> -<br><code>-+</code> <em>filename arg1 ...</em></dt> -<dd>Takes the next argument as a file name as usual, but takes all -remaining arguments (even if they have the syntactic form of switches) and -defines the name <code>ARGUMENTS</code> in userdict (not systemdict) as -an array of those strings, <em>before</em> running the file. When - Ghostscript finishes executing the file, it exits back to the shell.</dd> -</dl> - -<dl> - <dt><code>-@</code> <em>filename arg1 ...</em></dt> -<dd>Does the same thing as <code>--</code> and <code>-+</code>, but - expands <code>@</code><em>filename</em> arguments.</dd> -</dl> - -<dl> -<dt><code>-</code> - <br><code>-_</code></dt> -<dd>These are not really switches: they tell Ghostscript to read from -standard input, which is coming from a file or a pipe, -with or without buffering. -On some systems, Ghostscript may read the input one character at a time, -which is useful for programs such as ghostview that generate input for -Ghostscript dynamically and watch for some response, but can slow processing. -If performance is significantly slower than with a named file, -try '<code>-_</code>' which always reads the input in blocks. - However, '<code>-</code>' is equivalent on most systems.</dd> -</dl> - -<dl> -<dt><code>-c</code> <em>token ...</em> - <br><code>-c</code> <em>string ...</em></dt> -<dd>Interprets arguments as PostScript code up to the next argument that -begins with "<code>-</code>" followed by a non-digit, or with -"<code>@</code>". For example, if the file <code>quit.ps</code> -contains just the word "<code>quit</code>", then -<code>-c quit</code> on the command line is equivalent to -<code>quit.ps</code> there. Each argument must be valid PostScript, -either individual tokens as defined by the <code>token</code> operator, - or a string containing valid PostScript. -<p> -Because Ghostscript must initialize the PostScript environment -before executing the commands specified by this option it should -be specified after other setup options. Specifically this option -'bind's all operations and sets the systemdict to readonly.</p> -</dd> -</dl> - -<dl> - <dt><code>-f</code></dt> -<dd>Interprets following non-switch arguments as file names to be executed -using the normal <code>run</code> command. Since this is the default -behavior, <code>-f</code> is useful only for terminating the list of - tokens for the <code>-c</code> switch.</dd> -</dl> - -<dl> - <dt><code>-f</code><em>filename</em></dt> -<dd>Execute the given file, even if its name begins with a - "<code>-</code>" or "<code>@</code>".</dd> -</dl> - -<h4><a name="File_searching"></a>File searching</h4> - -<p> -Note that by "library files" here we mean all the files identified using -the search rule under "<a href="#Finding_files">How Ghostscript finds -files</a>" above: Ghostscript's own initialization files, fonts, and files - named on the command line.</p> - -<dl> - <dt><a name="I_switch"></a><code>-I</code><em>directories</em> -<br><code>-I </code><em>directories</em></dt> -<dd>Adds the designated list of directories at the head of the search path - for library files.</dd> -</dl> - -<dl> - <dt><a name="P_switch"></a><code>-P</code></dt> -<dd>Makes Ghostscript look first in the current directory for library - files.</dd> -</dl> - -<dl> - <dt><a name="P-_switch"></a><code>-P-</code></dt> -<dd>Makes Ghostscript <b><em>not</em></b> look first in the current -directory for library files (unless, of course, the first explicitly - supplied directory is "<code>.</code>"). This is now the default.</dd> -</dl> - -<h4><a name="Parameters"></a>Setting parameters</h4> - -<dl> -<dt><code>-D</code><em>name</em> - <br><code>-d</code><em>name</em></dt> - <dd>Define a name in systemdict with value=true.</dd> -</dl> - -<dl> -<dt><code>-D</code><em>name</em><code>=</code><em>token</em> - <br><code>-d</code><em>name</em><code>=</code><em>token</em></dt> -<dd>Define a name in systemdict with the given value. The value must be -a valid PostScript token (as defined by the <code>token</code> operator). -If the token is a non-literal name, it must be true, false, or null. -It is recommeded that this is used only for simple values -- use -<code>-c</code> (above) for complex values such as procedures, -arrays or dictionaries. -<br>Note that these values are defined <b>before</b> other names in -systemdict, so any name that that conflicts with one usually in -systemdict will be replaced by the normal definition during the - interpreter initialization.</dd> -</dl> - -<dl> -<dt><code>-S</code><em>name</em><code>=</code><em>string</em> - <br><code>-s</code><em>name</em><code>=</code><em>string</em></dt> -<dd>Define a name in systemdict with a given string as value. This is -different from <code>-d</code>. For example, <code>-dXYZ=35</code> - on the command line is equivalent to the program fragment - -<blockquote><code> -/XYZ 35 def -</code></blockquote> - -<p> -whereas <code>-sXYZ=35</code> is equivalent to</p> - -<blockquote><code> -/XYZ (35) def -</code></blockquote> -</dd> -</dl> - -<dl> -<dt><code>-p</code><em>name</em><code>=</code><em>string</em></dt> -<dd>Define a name in systemdict with the parsed version of the given string as value. The string takes a parameter definition in (something very close to) postscript format. -This allows more complex structures to be passed in than is possible with <code>-d</code> or <code>-s</code>. For example: - -<blockquote><code> --pFoo="<< /Bar[1 2 3]/Baz 0.1 /Whizz (string) /Bang <0123> >>" -</code></blockquote> - -<p>This means that <code>-p</code> can do the job of both <code>-d</code> and <code>-s</code>. For example:</p> - -<blockquote><code> --dDownScaleFactor=3 -</code></blockquote> - -<p>can be equivalently performed by</p> - -<blockquote><code> --pDownScaleFactor=3 -</code></blockquote> - -and - -<blockquote><code> --sPAPERSIZE=letter -</code></blockquote> - -<p>can be equivalently performed by</p> - -<blockquote><code> --pPAPERSIZE="(letter)" -</code></blockquote> - -<p>Note, that there are some 'special' values that should be set using <code>-s</code>, not <code>-p</code>, such as <code>DEVICE</code> and <code>DefaultGrayProfile</code>. Broadly, only use <code>-p</code> if you cannot set what you want using <code>-s</code> or <code>-d</code>.</p> - -<p>Also, internally, after setting an parameter with <code>-p</code> we perform an <code>initgraphics</code> operation. This is required to allow changes in parameters such as <code>HWResolution</code> to take effect. This means that attempting to use <code>-p</code> other than at the start of a page is liable to give unexpected results.</p> -</dl> - -<dl> - <dt><code>-u</code><em>name</em></dt> - <dd>Un-define a name, cancelling <code>-d</code> or <code>-s</code>. - -<p> -Note that the initialization file <code>gs_init.ps</code> makes -<code>systemdict</code> read-only, so the values of names defined with -<code>-D</code>, <code>-d</code>, <code>-S</code>, and -<code>-s</code> cannot be changed -- although, of course, they can be -superseded by definitions in <code>userdict</code> or other dictionaries. -However, device parameters set this way (<code>PageSize</code>, -<code>Margins</code>, etc.) are <em>not</em> read-only, and <em>can</em> -be changed by code in PostScript files.</p> -</dd> -</dl> - -<dl> - <dt><code>-g</code><em>number1</em><code>x</code><em>number2</em></dt> -<dd>Equivalent to <code>-dDEVICEWIDTH=</code><em>number1</em> and -<code>-dDEVICEHEIGHT=</code><em>number2</em>, specifying the device -width and height in pixels for the benefit of devices such as X11 windows -and VESA displays that require (or allow) you to specify width and height. -Note that this causes documents of other sizes to be clipped, not scaled: - see <code>-dFIXEDMEDIA</code> below. -</dd> -</dl> - -<dl> -<dt><a name="Resolution_switch"></a><code>-r</code><em>number</em> (same -as <code>-r</code><em>number</em><code>x</code><em>number</em>) - <br><code>-r</code><em>number1</em><code>x</code><em>number2</em></dt> -<dd>Equivalent to <code>-dDEVICEXRESOLUTION=</code><em>number1</em> and -<code>-dDEVICEYRESOLUTION=</code><em>number2</em>, specifying the device -horizontal and vertical resolution in pixels per inch for the benefit of - devices such as printers that support multiple X and Y resolutions.</dd> -</dl> - -<h4><a name="Quiet"></a>Suppress messages</h4> - -<dl> - <dt><a name="Quiet"></a><code>-q</code></dt> -<dd>Quiet startup: suppress normal startup messages, and also do the - equivalent of <a href="#dQUIET"><code>-dQUIET</code></a>.</dd> -</dl> - -<h3><a name="Parameter_switches"></a>Parameter switches (<code>-d</code> and <code>-s</code>)</h3> - -<p> -As noted above, <code>-d</code> and <code>-s</code> define initial -values for PostScript names. Some of these names are parameters that -control the interpreter or the graphics engine. You can also use -<code>-d</code> or <code>-s</code> to define a value for any device -parameter of the initial device (the one defined with -<code>-sDEVICE=</code>, or the default device if this switch is not -used). For example, since the <code>ppmraw</code> device has a numeric -<code>GrayValues</code> parameter that controls the number of bits per -component, <code>-sDEVICE=ppmraw -dGrayValues=16</code> will make this -the default device and set the number of bits per component to 4 (log2(16)).</p> - -<h4><a name="Rendering_parameters"></a>Rendering parameters</h4> - -<dl> -<dt><code>-dCOLORSCREEN -<br>-dCOLORSCREEN=0 - <br>-dCOLORSCREEN=false</code></dt> -<dd>On high-resolution devices (at least 150 dpi resolution, or -<code>-dDITHERPPI</code> specified), <code>-dCOLORSCREEN</code> -forces the use of separate halftone screens with different angles for CMYK -or RGB if halftones are needed (this produces the best-quality output); -<code>-dCOLORSCREEN=0</code> uses separate screens with the same -frequency and angle; <code>-dCOLORSCREEN=false</code> forces the use of -a single binary screen. The default if <code>COLORSCREEN</code> is not -specified is to use separate screens with different angles if the device -has fewer than 5 bits per color, and a single binary screen (which is never - actually used under normal circumstances) on all other devices.</dd> -</dl> - -<dl> - <dt><code>-dDITHERPPI=</code><em>lpi</em></dt> -<dd>Forces all devices to be considered high-resolution, and forces use of -a halftone screen or screens with <em>lpi</em> lines per inch, disregarding -the actual device resolution. Reasonable values for <em>lpi</em> are -<b><em>N</em></b>/5 to <b><em>N</em></b>/20, where <b><em>N</em></b> is the - resolution in dots per inch.</dd> -</dl> - -<dl> - <dt><code>-dInterpolateControl=</code><em>control_value</em></dt> - <dd>This allows control of the image interpolation. - -<p> -By default <code>InterpolateControl</code> is 1 and the image rendering -for images that have <code>/Interpolate true</code> are interpolated to -the full device resolution. Otherwise, images are rendered using the nearest -neighbour scaling (Bresenham's line algorithm through the image, plotting -the closest texture coord at each pixel). When downscaling this results -in some source pixels not appearing at all in the destination. When upscaling, -each source pixels will cover at least one destination pixel.</p> - -<p> -When the <em>control_value</em> is 0 no interpolation is performed, whether -or not the file has images with <code>/Interpolate true</code>.</p> - -<p> -When the <em>control_value</em> is greater than 1 interpolation is performed for -images with <code>/Interpolate true</code> as long as the image scaling -factor on either axis is larger than the <em>control_value</em>. Also, the -interpolation only produces images that have <em>(device resolution / control_value)</em> -maximum resolution rather than full device resolution. This allows for a performance -vs. quality tradeoff since the number of pixels produced by the interpolation -will be a fraction of the interpolated pixels at full device resolution. Every source -pixel will contribute partially to the destination pixels.</p> - -<p> -When the <code>InterpolateControl</code> <em>control_value</em> is less than 0 -interpolation is <b>forced</b> as if all images have <code>/Interpolate true</code>, -and the interpolation is controlled by the absolute value of the <em>control_value</em> -as described above. Thus, <code>-dInterpolateControl=-1</code> forces all images -to be interpolated at full device resolution.</p> - -<p> -Computationally, image interpolation is much more demanding than without -interpolation (lots of floating point muliplies and adds for every output -pixel vs simple integer additions, subtractions, and shifts).</p> - -<p> -In all but special cases image interpolation uses a Mitchell filter function -to scale the contributions for each output pixel. When upscaling, every output -pixel ends up being the weighted sum of 16 input pixels, When downscaling more -source pixels will contribute to the interpolated pixels. Every source pixel has -some effect on the output pixels.</p> -</dd> -</dl> -<dl> -<dt><code>-dDOINTERPOLATE</code></dt> -<dd>This option still works, but is deprecated, and is the equivalent of - <code>-dInterpolateControl=-1</code>.</dd> -</dl> -<dl> -<dt><code>-dNOINTERPOLATE</code></dt> -<dd> -This option still works, but is deprecated and is -the equivalent of <code>-dInterpolateControl=0</code> -</dd> -</dl> - -<dl> - <dt><code>-dTextAlphaBits=</code><em>n</em></dt> - <dt><code>-dGraphicsAlphaBits=</code><em>n</em></dt> -<dd>These options control the use of subsample antialiasing. Their use is highly recommended for producing high quality rasterizations. The subsampling box size <em>n</em> should be 4 for optimum output, but smaller values can be used for faster rendering. Antialiasing is enabled separately for text and graphics content. - Allowed values are 1, 2 or 4. -<p> -Note that because of the way antialiasing blends the edges of shapes into the background when -they are drawn some files that rely on joining separate filled polygons together to cover -an area may not render as expected with <code>GraphicsAlphaBits</code> at 2 or 4. If you encounter -strange lines within solid areas, try rendering that file again with -<code>-dGraphicsAlphaBits=1</code>.</p> -<p>Further note; because this feature relies upon rendering the input it is incompatible, and will generate -an error on attempted use, with any of the vector output devices.</p> -</dd> -</dl> - -<dl> - <dt><code>-dAlignToPixels=</code><em>n</em></dt> -<dd>Chooses glyph alignent to integral pixel boundaries (if set to the value 1) -or to subpixels (value 0). Subpixels are a smaller raster grid -which is used internally for text antialiasing. -The number of subpixels in a pixel usually is <code>2^TextAlphaBits</code>, -but this may be automatically reduced for big characters to save space - in character cache. - -<p> -The parameter has no effect if <code>-dTextAlphaBits=1</code>. -Default value is 0.</p> - -<p> -Setting <code>-dAlignToPixels=0</code> can improve rendering -of poorly hinted fonts, but may impair the appearance of well-hinted fonts.</p> -</dd> -</dl> - -<dl> - <dt><code>-dGridFitTT=</code><em>n</em></dt> -<dd> This specifies the initial value for the implementation specific -user parameter <a href="Language.htm#GridFitTT">GridFitTT</a>. -It controls grid fitting of True Type fonts -(Sometimes referred to as "hinting", but strictly speaking -the latter is a feature of Type 1 fonts). -Setting this to 2 enables automatic grid fitting for True Type glyphs. -The value 0 disables grid fitting. The default value is 2. -For more information see the description of the user parameter - <a href="Language.htm#GridFitTT">GridFitTT</a>.</dd> - -</dl> - -<dl> - <dt><code>-dUseCIEColor</code></dt> -<dd>Set UseCIEColor in the page device dictionary, remapping device-dependent -color values through a Postscript defined CIE color space. Document DeviceGray, -DeviceRGB and DeviceCMYK source colors will be substituted respectively by Postscript -CIEA, CIEABC and CIEDEFG color spaces. See the document -<a href="GS9_Color_Management.pdf">GS9 Color Management</a> for details on how -this option will interact with Ghostscript's ICC-based color workflow. If accurate colors - are desired, it is recommended that an ICC workflow be used.</dd> -</dl> - -<dl> - <dt><code>-dNOCIE</code></dt> -<dd>Substitutes <code>DeviceGray</code> for CIEBasedA, <code>DeviceRGB</code> for CIEBasedABC and CIEBasedDEF spaces and <code>DeviceCMYK</code> -fpr CIEBasedDEFG color spaces. Useful only on - very slow systems where color accuracy is less important.</dd> -</dl> - -<dl> - <dt><code>-dNOSUBSTDEVICECOLORS</code></dt> -<dd>This switch prevents the substitution of the <code>ColorSpace</code> -resources (<code>DefaultGray</code>, <code>DefaultRGB</code>, and -<code>DefaultCMYK</code>) for the <code>DeviceGray</code>, -<code>DeviceRGB</code>, and <code>DeviceCMYK</code> color spaces. -This switch is primarily useful for PDF creation using the <code>pdfwrite</code> -device when retaining the color spaces from the original document is - important.</dd> -</dl> - -<dl> - <dt><code>-dNOPSICC</code></dt> -<dd>Disables the automatic loading and use of an input color space that is -contained in a PostScript file as DSC comments starting with the %%BeginICCProfile: -comment. ICC profiles are sometimes embedded by applications to convey the exact -input color space allowing better color fidelity. Since the embedded ICC profiles -often use multidimensional RenderTables, color conversion may be slower than using -the Default color conversion invoked when the <code>-dUseCIEColor</code> -option is specified, therefore the <code>-dNOPSICC</code> option may result - in improved performance at slightly reduced color fidelity.</dd> -</dl> - -<dl> - <dt><code>-dNOINTERPOLATE</code></dt> -<dd>Turns off image interpolation, improving performance on interpolated -images at the expense of image quality. <code>-dNOINTERPOLATE</code> - overrides <code>-dDOINTERPOLATE</code>.</dd> -</dl> - -<dl> - <dt><code>-dNOTRANSPARENCY</code></dt> -<dd>Turns off PDF 1.4 transparency, resulting in faster (but possibly -incorrect) rendering of pages containing PDF 1.4 transparency and - blending.</dd> -</dl> - -<a name="ALLOWPSTRANSPARENCY"></a> -<dl> - <dt><code>-dALLOWPSTRANSPARENCY</code></dt> -<dd> -Enables the use of the Ghostscript custom transparency operators -(<a href="Language.htm#Transparency">Transparency</a>) from -Postscript input. Normally, these operators are not accessible from Postscript -jobs, being primarily intended to be called by the PDF interpreter. Using -<code>-dALLOWPSTRANSPARENCY</code> leaves them available. It is important that -these operators are used correctly, especially the order in which they are called, -otherwise unintended, even undefined behavior may result. -</dd> -</dl> - -<dl> - <dt><code>-dNO_TN5044</code></dt> -<dd>Turns off the TN 5044 psuedo operators. These psuedo operators are not a part -of the official Postscript specification. However they are defined in <i>Technical -Note #5044 Color Separation Conventions for PostScript Language Programs</i>. -These psuedo operators are required for some files from QuarkXPress. However some -files from Corel 9 and Illustrator 88 do not operate properly if these operators - are present.</dd> -</dl> - -<dl> - <dt><code>-dDOPS</code></dt> -<dd>Enables processing of Subtype /PS streams in PDF files and the DoPS operator. -DoPS has in fact been deprecated for some time. Also the "PS" operator that was -removed from the 1.3 2nd edition specification is also disabled by default, and -enabled by <code>-dDOPS</code>. Use of this option is <b>NOT</b> -recommended in security-conscious applications, as it increases the -scope for malicious code. <code>-dDOPS</code> has no effect on -processing of PostScript source files. Note: in releases 7.30 and - earlier, processing of DoPS was always enabled.</dd> -</dl> - -<a name="BlackText"></a> -<dl> - <dt><code>-dBlackText</code></dt> -<dd>Forces text to be drawn with black. This occurs for text fill and -text stroke operations. PDF output created with this setting will be -updated to be drawn with gray values of 0. Type 3 fonts, which are -sometimes used for graphics, are not affected by this parameter. </dd> -</dl> - -<h4><a name="Page_parameters"></a>Page parameters</h4> - -<dl> - <dt><code>-dFirstPage=</code><em>pagenumber</em></dt> -<dd>Begin on the designated page of the document. - Pages of all documents in PDF collections are numbered sequentionally.</dd> -</dl> - -<dl> - <dt><code>-dLastPage=</code><em>pagenumber</em></dt> -<dd>Stop after the designated page of the document. - Pages of all documents in PDF collections are numbered sequentionally.</dd> -</dl> - -<dl> -<dt><code>-sPageList=</code><em>pagenumber</em></dt> -<dd>There are three possible values for this; even, odd or a list of pages to be processed. -A list can include single pages or ranges of pages. -Ranges of pages use the minus sign '-', individual pages and ranges of pages are separated - by commas ','. A trailing minus '-' means process all remaining pages. For example; -<p><blockquote><pre> --sPageList=1,3,5 indicates that pages 1, 3 and 5 should be processed. --sPageList=5-10 indicates that pages 5, 6, 7, 8, 9 and 10 should be processed. --sPageList=1, 5-10, 12- indicates that pages 1, 5, 6, 7, 8, 9, 10 and 12 onwards should be processed. -</pre></blockquote> -</p> - -<p>The PDF interpreter and the other language interpreters handle these in slightly different ways. Because -PDF files enable random access to pages in the document the PDF inerpreter only interprets and renders -the required pages. PCL andPostScript cannot be handled in ths way, and so all the pages must be interpreted. -However only the requested pages are rendered, which can still lead to savings in time. Be aware that -using the '%d' syntax for OutputFile does not reflect the page number in the original document. If you -chose (for example) to process even pages by using <code>-sPageList=even</code>, then the output of -<code>-sOutputFile=out%d.png</code> would still be -out0.png, out1.png, out2.png etc...... -</p> -<p> -Because the PostScript and PCL interpreters cannot determine when a document terminates, sending multple -files as input on the command line does not reset the PageList between each document, each page in the second and -subsequent documents is treated as following on directly from the last page in the first document. The PDF -interpreter, however, does not work this way. Since it knows about individual PDF files the PageList -is applied to each PDF file separately. So if you were to set <code>-sPageList=1,2</code> and - then send two PDF files, the result would be pages 1 and 2 from the first file, and then pages 1 and 2 from the second - file. The PostScript interpreter, by contrast, would only render pages 1 and 2 from the first file. This means you must - exercise caution when using this switch, and probably should not use it at all when processing a mixture of PostScript - and PDF files on the same command line. -</p> -</dd> -</dl> - -<dl> - <dt><a name="FIXEDMEDIA"></a><code>-dFIXEDMEDIA</code></dt> -<dd>Causes the media size to be fixed after initialization, forcing pages -of other sizes or orientations to be clipped. This may be useful when -printing documents on a printer that can handle their requested paper size -but whose default is some other size. Note that <code>-g</code> -automatically sets <code>-dFIXEDMEDIA</code>, but - <code>-sPAPERSIZE=</code> does not.</dd> -</dl> - -<dl> - <dt><code>-dFIXEDRESOLUTION</code></dt> -<dd>Causes the media resolution to be fixed similarly. <code>-r</code> - automatically sets <code>-dFIXEDRESOLUTION</code>.</dd> -</dl> - -<dl> - <dt><code>-dPSFitPage</code></dt> -<dd>The page size from the PostScript file <code>setpagedevice</code> operator, -or one of the older <code>statusdict</code> page size operators (such as -<code>letter</code> or <code>a4</code>) will be rotated, scaled and centered on the -"best fit" page size from those availiable in the InputAttributes list. -The <code>-dPSFitPage</code> is most easily used to fit pages when used with the - <code>-dFIXEDMEDIA</code> option. - -<p> -This option is also set by the <code>-dFitPage</code> option.</p> -</dd> -</dl> - -<dl> - <dt><code>-dORIENT1=true -<br>-dORIENT1=false</code></dt> -<dd>Defines the meaning of the 0 and 1 orientation values for the -setpage[params] compatibility operators. The default value of -<code>ORIENT1</code> is true (set in <code>gs_init.ps</code>), which -is the correct value for most files that use setpage[params] at all, -namely, files produced by badly designed applications that "know" that the -output will be printed on certain roll-media printers: these applications -use 0 to mean landscape and 1 to mean portrait. -<code>-dORIENT1=false</code> declares that 0 means portrait and 1 means -landscape, which is the convention used by a smaller number of files - produced by properly written applications.</dd> -</dl> - -<dl> -<dt><code>-dDEVICEWIDTHPOINTS=</code><em>w</em> - <br><code>-dDEVICEHEIGHTPOINTS=</code><em>h</em></dt> -<dd>Sets the initial page width to <em>w</em> or initial page height to - <em>h</em> respectively, specified in 1/72" units.</dd> -</dl> - -<dl> - <dt><code>-sDEFAULTPAPERSIZE=</code><em>a4</em></dt> -<dd> -This value will be used to replace the device default papersize ONLY -if the default papersize for the device is 'letter' or 'a4' serving -to insulate users of A4 or 8.5x11 from particular device defaults -(the collection of contributed drivers in Ghostscript vary as to -the default size). -</dd> -</dl> - -<dl> - <dt><code>-dFitPage</code></dt> -<dd>This is a "convenience" operator that sets the various options to perform - page fitting for specific file types. -<p> -This option sets the <code>-dEPSFitPage</code>, <code>-dPDFFitPage</code>, and -the <code>-dFitPage</code> options.</p> -</dd> -</dl> - -<dl> -<dt><a name="NupControl"></a></dt> - <dt><code>-sNupControl=</code><em>Nup_option_string</em></dt> -<dd>This option specifies the N-up nesting to be performed. The pages are scaled -and arranged on the current PageSize "master" page according the the option. -<p> -The only option strings are as follows: - <ul> - <li> - <dl><dt></dt><dd><code>-sNupControl=</code><em>number1</em><code>x</code><em>number2</em></dd></dl> - will fit <em>number1</em> nested pages across the master page, and <em>number2</em> - down the master page, from the upper left, then to the right to fill the row, moving down - to the leftmost place on the next row until the nest is complete. - <p> - A partially filled nest will be output when the <code>-sNupControl=</code> string is changed, - when Ghostscript exits, or when the page size changes. - <p> - Pages are scaled to fit the requested number horizontally and vertically, maintaining the - aspect ratio. If the scaling selected for fitting the nested pages leaves space horizontally - on the master page, the blank area will be added to the left and right of the <b>entire</b> - row of nested pages. If the fit results in vertical space, the blank area will be added - above and below <b>all</b> of the rows. - </li> - <li> - <dl><dt></dt><dd><code>-sNupControl=</code></dd></dl> - An empty string will turn off nesting. If there are any nested pages on the master page, - the partially filled master page will be output. - </li> - </ul> -<p>Printer devices typically reallocate their memory whenever the transparency use -of a page changes (from one page having transparency, to the next page not having -transparency, or vice versa). This would cause problems with Nup, possibly leading -to lost or corrupt pages in the output. To avoid this, the Nup device changes -the parameters of the page to always set the PageUsesTransparency flag. While this -should be entirely transparent for the user and not cause extra transparency blending -operations during the standard rendering processes for most devices, it may cause -devices to use the clist rather than PageMode. -</dd> -</dl> - -<h4><a name="Font_related_parameters"></a>Font-related parameters</h4> - -<dl> - <dt><code>-dLOCALFONTS</code></dt> -<dd>Causes Type 1 fonts to be loaded into the current VM -- normally local -VM -- instead of always being loaded into global VM. Useful only for - compatibility with Adobe printers for loading some obsolete fonts.</dd> -</dl> - -<dl> - <dt><a name="FONTMAP_switch"></a><code>-dNOFONTMAP</code></dt> -<dd>Suppresses the normal loading of the Fontmap file. This may be useful - in environments without a file system.</dd> -</dl> - -<dl> - <dt><code>-dNOFONTPATH</code></dt> -<dd>Suppresses consultation of <code>GS_FONTPATH</code>. This may be - useful for debugging.</dd> -</dl> - -<dl> - <dt><code>-dNOPLATFONTS</code></dt> -<dd>Disables the use of fonts supplied by the underlying platform (X -Windows or Microsoft Windows). This may be needed if the platform fonts - look undesirably different from the scalable fonts.</dd> -</dl> - -<dl> - <dt><code>-dNONATIVEFONTMAP</code></dt> -<dd>Disables the use of font map and corresponding fonts supplied by the -underlying platform. This may be needed to ensure consistent rendering on - the platforms with different fonts, for instance, during regression testing.</dd> -</dl> - -<dl> -<dt><code>-sFONTMAP=</code><em>filename1</em><code>;</code><em>filename2</em><code>;</code><em>...</em></dt> -<dd>Specifies alternate name or names for the Fontmap file. Note that the -names are separated by "<code>:</code>" on Unix systems, by -"<code>;</code>" on MS Windows systems, and by -"<code>,</code>" on VMS systems, just as for search paths.</dd> -</dl> - -<dl> - <dt><code>-sFONTPATH=</code><em>dir1</em><code>;</code><em>dir2</em><code>;</code><em>...</em></dt> -<dd>Specifies a list of directories that will be scanned when looking for -fonts not found on the search path, overriding the environment variable - <code>GS_FONTPATH</code>. -<p>By implication, any paths specified by <code>FONTPATH</code> or <code>GS_FONTPATH</code> are automatically -added to the <code>permit file read</code> list (see "<a href="#Safer">-dSAFER</a>"). -</dd> -</dl> - -<dl> - <dt><code>-sSUBSTFONT=</code><em>fontname</em></dt> -<dd>Causes the given font to be substituted for all unknown fonts, instead -of using the normal intelligent substitution algorithm. Also, in this -case, the font returned by <code>findfont</code> is the actual font -named <em>fontname</em>, not a copy of the font with its -<code>FontName</code> changed to the requested one. -THIS OPTION SHOULD NOT BE USED WITH HIGH LEVEL (VECTOR) DEVICES, such as -<code>pdfwrite</code>, because it prevents such devices from -providing the original font names in the output document. The -font specified (<em>fontname</em>) will be embedded instead, -limiting all future users of the document to the same approximate - rendering.</dd> -</dl> - -<h4><a name="Resource_related_parameters"></a>Resource-related parameters</h4> - -<dl> - <dt><a name="GenericResourceDir"></a><code>-sGenericResourceDir=path</code></dt> -<dd>Specifies a path to resource files. - The value is platform dependent. It must end with a directory separator. -<p> -<b><font size="+1"> -A note for Windows users, Artifex recommends the use of the -forward slash delimiter due to the special interpretation of \" by -the Microsoft C startup code. See -<a href="http://msdn.microsoft.com/en-us/library/a1y7w461.aspx">Parsing C Command-Line Arguments</a> -for more information. - </font></b></p> -<p> -Adobe specifies <code>GenericResourceDir</code> to be an absolute path -to a single resource directory. Ghostscript instead maintains -multiple resource directories and uses an extended method for finding -resources, which is explained in -<a href="#PS_resources">"Finding PostScript Level 2 resources"</a>.</p> -<p> -Due to the extended search method, Ghostscript uses <code>GenericResourceDir</code> -only as a default directory for resources being not installed. -Therefore <code>GenericResourceDir</code> may be considered as a place -where new resources to be installed. The default implementation of the function -<code>ResourceFileName</code> uses <code>GenericResourceDir</code> when -(1) it is an absolute path, or (2) the resource file is absent. -The extended search method does not call <code>ResourceFileName</code> .</p> -<p> -Default value is <code>(./Resource/)</code> for Unix, and an equivalent one on other -platforms.</p> -</dd> -</dl> - -<dl> - <dt><a name="FontResourceDir"></a><code>-sFontResourceDir=path</code></dt> -<dd>Specifies a path where font files are installed. - It's meaning is similar to <code>GenericResourceDir</code>. - -<p> -Default value is <code>(./Font/)</code> for Unix, and an equivalent one on other -platforms.</p> -</dd> -</dl> - - - -<h4><a name="Interaction_related_parameters"></a>Interaction-related parameters</h4> - -<dl> - <dt><code>-dBATCH</code></dt> -<dd>Causes Ghostscript to exit after processing all files named on the -command line, rather than going into an interactive loop reading PostScript - commands. Equivalent to putting -c quit at the end of the command line.</dd> -</dl> - -<dl> - <dt><code>-dNOPAGEPROMPT</code></dt> -<dd>Disables only the prompt, but not the pause, at the end of each page. -This may be useful on PC displays that get confused if a program attempts - to write text to the console while the display is in a graphics mode.</dd> -</dl> - -<dl> - <dt><a name="NoPause"></a><code>-dNOPAUSE</code></dt> -<dd>Disables the prompt and pause at the end of each page. Normally one -should use this (along with <code>-dBATCH</code>) when producing output -on a printer or to a file; it also may be desirable for applications where - another program is "driving" Ghostscript.</dd> -</dl> - -<dl> - <dt><code>-dNOPROMPT</code></dt> -<dd>Disables the prompt printed by Ghostscript when it expects interactive -input, as well as the end-of-page prompt (<code>-dNOPAGEPROMPT</code>). -This allows piping input -directly into Ghostscript, as long as the data doesn't refer to - <code>currentfile</code>.</dd> -</dl> - -<dl> - <dt><a name="dQUIET"></a><code>-dQUIET</code></dt> -<dd>Suppresses routine information comments on standard output. This is - currently necessary when redirecting device output to standard output.</dd> -</dl> - -<dl> - <dt><code>-dSHORTERRORS</code></dt> - <dd>Makes certain error and information messages more Adobe-compatible.</dd> -</dl> - -<dl> - <dt><code>-sstdout=</code><em>filename</em></dt> -<dd>Redirect PostScript <code>%stdout</code> to a file or -<code>stderr</code>, to avoid it being mixed with device stdout. -To redirect stdout to stderr use <code>-sstdout=%stderr</code>. -To cancel redirection of stdout use <code>-sstdout=%stdout</code> - or <code>-sstdout=-</code>. -<p> -Note that this redirects PostScript output to %stdout but <b>does not</b> -change the destination FILE of device output as with <code>-sOutputFile=-</code> -or even <code>-sOutputFile=%stdout</code> since devices write directly using -the stdout FILE * pointer with C function calls such as fwrite or fputs.</p> -</dd> -</dl> - -<dl> - <dt><code>-dTTYPAUSE</code></dt> -<dd> -Causes Ghostscript to read a character from <code>/dev/tty</code>, -rather than standard input, at the end of each page. This may be useful if -input is coming from a pipe. Note that <code>-dTTYPAUSE</code> -overrides <code>-dNOPAUSE</code>. -</dl> - -<h4><a name="Output_selection_parameters"></a>Device and output selection parameters</h4> - -<dl> - <dt><code>-dNODISPLAY</code></dt> -<dd>Initializes Ghostscript with a null device (a device that discards the -output image) rather than the default device or the device selected with -<code>-sDEVICE=</code>. This is usually useful only when running -PostScript code whose purpose is to compute something rather than to - produce an output image.</dd> -</dl> - -<dl> - <dt><a name="DEVICE_switch"></a><code>-sDEVICE=</code><em>device</em></dt> -<dd>Selects an alternate <a href="#Output_device">initial output - device</a>.</dd> -</dl> - -<dl> - <dt><code>-sOutputFile=</code><em>filename</em></dt> -<dd>Selects an alternate output file (or pipe) for the initial output - device, as described above.</dd> -</dl> - -<dl> - <dt><code>-d.IgnoreNumCopies=true</code></dt> -<dd>Some devices implement support for "printing" multiple copies of the -input document and some do not, usually based on whether it makes sense -for a particular output format. This switch instructs all devices to -ignore a request to print multiple copies, giving more consistent - behaviour.</dd> -</dl> - -<h4><a name="Deferred_Page_Rendering"></a>Deferred Page Rendering</h4> -<dl> - <dt></dt> -<dd>Raster printers and image formats that can use the "command list" (clist) -to store a representation of the page prior to rendering can use the -<code>--saved-pages=</code><em>string</em> on the command line for - deferred rendering of pages. -<p> -Pages that are <em>saved</em> instead of printed are retained until the -list of saved pages is emptied by the <code>flush</code> command of the -<code>saved-pages=</code> command string.</p> -<p> -Pages can be printed in reverse or normal order, or selected pages, -including all even or all odd, and multiple collated copies can be produced. -Since pages are saved until the <code>flush</code> command, pages can be -printed multiple times, in any order.</p> -<p> -Refer to the <a href="SavedPages.htm">SavedPages</a> document for -details.</p> -</dd> -</dl> - -<h4><a name="EPS_parameters"></a>EPS parameters</h4> - -<dl> - <dt><code>-dEPSCrop</code></dt> -<dd>Crop an EPS file to the bounding box. - This is useful when converting an EPS file to a bitmap.</dd> -</dl> - -<dl> - <dt><code>-dEPSFitPage</code></dt> -<dd>Resize an EPS file to fit the page. - This is useful for shrinking or enlarging an EPS file to fit the paper size when printing. -<p> -This option is also set by the <code>-dFitPage</code> option.</p> -</dd> -</dl> - -<dl> - <dt><code>-dNOEPS</code></dt> -<dd>Prevent special processing of EPS files. -This is useful when EPS files have incorrect Document - Structuring Convention comments. -</dd> -</dl> - -<h4><a name="ICC_color_parameters"></a>ICC color parameters</h4> - -<dl> -<dt></dt> -<dd> -For details about the ICC controls see the document -<a href="GS9_Color_Management.pdf">GS9 Color Management</a>. -</dd> -</dl> - -<dl> - <dt><code>-sDefaultGrayProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -undefined device gray color spaces. If this is not set, -the profile file name "default_gray.icc" will be used as - the default.</dd> -</dl> - -<dl> - <dt><code>-sDefaultRGBProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -undefined device RGB color spaces. If this is not set, -the profile file name "default_rgb.icc" will be used as - the default.</dd> -</dl> - -<dl> - <dt><code>-sDefaultCMYKProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -undefined device CMYK color spaces. If this is not set, -the profile file name "default_cmyk.icc" will be used as - the default.</dd> -</dl> - -<dl> - <dt><code>-sDeviceNProfile=</code><em>filename</em></dt> -<dd>Associate a DeviceN color space contained in a PS or PDF -document with an ICC profile. Note that neither PS nor PDF provide -in-document ICC profile definitions for DeviceN color spaces. -With this interface it is possible to provide this definition. -The colorants tag order in the ICC profile defines the lay-down -order of the inks associated with the profile. A windows-based -tool for creating these source profiles is contained in - ./toolbin/color/icc_creator.</dd> -</dl> - -<dl> - <dt><code>-sOutputICCProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -the output device. Care should be taken to ensure that the -number of colorants associated with the device is the same -as the profile. If this is not set, an appropriate profile -(i.e. one with the proper number of colorants) will be -selected from those in the directory specified by ICCProfilesDir (see below). - Note that if the output device is CMYK + spot colorants, a CMYK -profile can be used to provide color management for the CMYK colorants only. -In this case, spot colors will pass through unprocessed assuming the -device supports those colorants. It is also possible for these devices to - specify NCLR ICC profiles for output.</dd> -</dl> - -<dl> - <dt><code>-sICCOutputColors=</code><em>"Cyan, Magenta, Yellow, Black, Orange, Violet"</em></dt> -<dd>For the psdcmyk and tiffsep separation devices, the device ICC profile can -be an NCLR profile, which means something that includes non-traditional inks -like Orange, Violet, etc. In this case, the list of the color names in the -order that they exist in the profile must be provided with this command line -option. Note that if a color name that is specified for the profile occurs also within -the document (e.g. "Orange" above), then these color names will be associated with -the same separation. Additional names beyond those of the ICC profile component count -can be included. In this case, those components will be installed into the tiffsep -or psdcmyk device list of colors, following the ICC profile colors. -The number of spot colors (those that go beyond the standard CMYK colors) -allowed by tiffsep or psdcmyk can be set using -dMaxSpots=#. The default -value for this is currently set to 10 (GS_SOFT_MAX_SPOTS). -As an example consider the case where we wish to use a 6CLR ICC profile that -includes Orange and Violet, but -need the device to include a specialty color component such as -Varnish, which does not appear in the document and is not handled by the 6CLR ICC -profile. In addition, we desire -to allow one more spot color of the document to come through to our device. For -this case using - <code>-sICCOutputColors=</code><em>"Cyan, Magenta, Yellow, Black, Orange, Violet, Varnish"</em> - <code>-dMaxSpots=</code><em>4</em> - <code>-sOutputICCProfile=</code><em>My_6CLR_Profile.icc</em> -would provide the desired outcome. Note that it is up to the device or -through the use of -sNamedProfile (see below) to involve the setting -of any values in the Varnish channel. However, if an All color value is encountered -in the document, the Varnish component will have its value -set as will the Orange and Violet values (Likewise if a spot color named Varnish is -encountered in the document the Varnish component will be used for the values). -The All value is typically used -for placing registration targets on separations. -Finally, note that if an NCLR ICC profile is specified -and ICCOutputColors is not used, then a set of default names will be used for -the extra colorants (non-CMYK) in the profile. These names are given as ICC_COLOR_N for -the Nth non-CMYK channel.</dd> -</dl> - -<dl> - <dt><code>-sProofProfile=</code><em>filename</em></dt> -<dd> -Enable the specificiation of a proofing profile that will make the -color management system link multiple profiles together to emulate the -device defined by the proofing profile. See the document - <a href="GS9_Color_Management.pdf">GS9 Color Management</a> for details about this option.</dd> -</dl> - -<dl> - <dt><code>-sDeviceLinkProfile=</code><em>filename</em></dt> -<dd>Define a device link profile. This profile is used following -the output device profile. Care should be taken to ensure that the -output device process color model is the same as the output color -space for the device link profile. In addition, the color space of -the OutputICCProfile should match the input color space of the device -link profile. For example, the following would be a valid specification --sDEVICE=tiff32nc -sOutputICCProfile=srgb.icc -sDeviceLinkProfile=linkRGBtoCMYK.icc. -In this case, the output device's color model is CMYK (tiff32nc) and the colors -are mapped through sRGB and through a devicelink profile that maps sRGB to -CMYK values. See the document - <a href="GS9_Color_Management.pdf">GS9 Color Management</a> for details about this option.</dd> -</dl> - -<dl> - <dt><code>-sNamedProfile=</code><em>filename</em></dt> -<dd>Define a structure that is to be used by the color management -module (CMM) to provide color management of named colors. While -the ICC does define a named color format, this structure can in -practice be much more general. Many developers wish to use -their own proprietary-based format for spot color management. -This command option is for developer use when an implementation -for named color management is designed for the function -gsicc_transform_named_color located in gsicccache.c . An example -implementation is currently contained in the code for the handling of both -Separation and DeviceN colors. For the general user this command option - should really not be used.</dd> -</dl> - -<dl> - <dt><code>-sBlendColorProfile=</code><em>filename</em></dt> -<dd>With the PDF transparency imaging model, a color space can -be specified within which the color blending operations are to -take place. Some files lack this specification, in which case -the blending occurs in the output device's native color space. This -dependency of blending color space on the device color model -can be avoided by using the above command to force a specific -color space in which to perform the blending. </dd> -</dl> - -<dl> - <dt><code>-dColorAccuracy=</code><em>0/1/2</em></dt> -<dd>Set the level of accuracy that should be used. A setting of 0 will result in less accurate -color rendering compared to a setting of 2. However, the creation of a transformation -will be faster at a setting of 0 compared to a setting of 2. - Default setting is 2.</dd> -</dl> - -<dl> - <dt><code>-dRenderIntent=</code><em>0/1/2/3</em></dt> -<dd>Set the rendering intent that should be used with the -profile specified above by -sOutputICCProfile. The -options 0, 1, 2, and 3 correspond to the ICC intents of Perceptual, Colorimetric, - Saturation, and Absolute Colorimetric.</dd> -</dl> - -<dl> - <dt><code>-dBlackPtComp=</code><em>0/1</em></dt> -<dd>Specify if black point compensation should be used with the - profile specified above by -sOutputICCProfile.</dd> -</dl> - -<dl> - <dt><code>-dKPreserve=</code><em>0/1/2</em></dt> -<dd>Specify if black preservation should be used when mapping -from CMYK to CMYK. When using littleCMS as the CMM, the code 0 -corresponds to no preservation, 1 corresponds to the PRESERVE_K_ONLY approach -described in the littleCMS documentation and 2 corresponds to the -PRESERVE_K_PLANE approach. This is only valid when using littleCMS for - color management.</dd> -</dl> - -<dl> - <dt><code>-sVectorICCProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -the output device for vector-based graphics (e.g. Fill, -Stroke operations). -Care should be taken to ensure that the -number of colorants associated with the device is the same -as the profile. This can be used to obtain more saturated - colors for graphics.</dd> -</dl> - -<dl> - <dt><code>-dVectorIntent=</code><em>0/1/2/3</em></dt> -<dd>Set the rendering intent that should be used with vector-based graphic objects. The - options are the same as specified for -dRenderIntent.</dd> -</dl> - -<dl> - <dt><code>-dVectorBlackPt=</code><em>0/1</em></dt> - <dd>Specify if black point compensation should be used for vector-based graphic objects.</dd> -</dl> - -<dl> - <dt><code>-dVectorKPreserve=</code><em>0/1/2</em></dt> -<dd>Specify if black preservation should be used when mapping -from CMYK to CMYK for vector-based graphic objects. The - options are the same as specified for -dKPreserve.</dd> -</dl> - -<dl> - <dt><code>-sImageICCProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -the output device for images. -Care should be taken to ensure that the -number of colorants associated with the device is the same -as the profile. This can be used to obtain perceptually - pleasing images.</dd> -</dl> - -<dl> - <dt><code>-dImageIntent=</code><em>0/1/2/3</em></dt> - <dd>Set the rendering intent that should be used for images.</dd> -</dl> - -<dl> - <dt><code>-dImageBlackPt=</code><em>0/1</em></dt> - <dd>Specify if black point compensation should be used with images.</dd> -</dl> - -<dl> - <dt><code>-dImageKPreserve=</code><em>0/1/2</em></dt> -<dd>Specify if black preservation should be used when mapping -from CMYK to CMYK for image objects. The - options are the same as specified for -dKPreserve.</dd> -</dl> - -<dl> - <dt><code>-sTextICCProfile=</code><em>filename</em></dt> -<dd>Set the ICC profile that will be associated with -the output device for text. -Care should be taken to ensure that the -number of colorants associated with the device is the same - as the profile. This can be used ensure K only text.</dd> -</dl> - -<dl> - <dt><code>-dTextIntent=</code><em>0/1/2/3</em></dt> -<dd>Set the rendering intent that should be used text objects. The - options are the same as specified for -dRenderIntent.</dd> -</dl> - -<dl> -<dt><code>-dTextBlackPt=</code><em>0/1</em></dt> - <dd>Specify if black point compensation should be used with text objects.</dd> -</dl> - -<dl> - <dt><code>-dTextKPreserve=</code><em>0/1/2</em></dt> -<dd>Specify if black preservation should be used when mapping -from CMYK to CMYK for text objects. The - options are the same as specified for -dKPreserve.</dd> -</dl> - -<dl> - <dt><code>-dOverrideICC</code></dt> -<dd>Override any ICC profiles contained in the source -document with the profiles specified by -sDefaultGrayProfile, sDefaultRGBProfile, sDefaultCMYKProfile. -Note that if no profiles are specified for the default -Device color spaces, then -the system default profiles will be used. For detailed override -control in the specification of source colors see - <a href="#SourceObjectICC">SourceObjectICC</a>.</dd> -</dl> - -<dl> - <dt><a name="SourceObjectICC"></a><code>-sSourceObjectICC=</code><em>filename</em></dt> -<dd> -This option provides an extreme level of override control to -specify the source color spaces and rendering intents to use -with vector-based graphics, images and text for both RGB and CMYK source -objects. The specification is made through a file that contains -on a line a key name to specify the object type (e.g. Image_CMYK) -followed by an ICC profile file name, a rendering intent -number (0 for perceptual, 1 for colorimetric, 2 for saturation, -3 for absolute colorimetric) and information for black point compensation, -black preservation, and source ICC override. It is also possible to turn -off color management for certain object types, use device link profiles for -object types and do custom color replacements. An example file is given in -./gs/toolbin/color/src_color/objsrc_profiles_example.txt. -Profiles to demonstrate this method of specification are also -included in this folder. Note that if objects are colorimetrically -specified through this mechanism other operations like -dImageIntent, --dOverrideICC, have no affect. See further details in the document - <a href="GS9_Color_Management.pdf">GS9 Color Management</a>.</dd> -</dl> - -<dl> - <dt><code>-dDeviceGrayToK=</code><em>true/false</em></dt> -<dd> -By default, Ghostscript will map DeviceGray color spaces to -pure K when the output device is CMYK based. This may not -always be desired. In particular, it may be desired to map -from the gray ICC profile specified by -sDefaultGrayProfile -to the output device profile. To achieve this, one should - specify -dDeviceGrayToK=false.</dd> -</dl> - -<dl> - <dt><code>-dUseFastColor=</code><em>true/false</em></dt> -<dd> -This is used to avoid the use of ICC profiles for source colors. This -includes those that are defined by DeviceGray, DeviceRGB and DeviceCMYK definitions -as well as ICC-based color spaces in the source document. With -UseFastColor set to true, the traditional Postscript 255 minus operations -are used to convert between RGB and CMYK with black generation and undercolor - removal mappings.</dd> -</dl> - -<dl> - <dt><code>-dSimulateOverprint=</code><em>true/false</em></dt> -<dd> -This option has been replaced by <code><b>-dOverprint=</b></code> -</dd> -</dl> - - -<dl> - - <dt><a name="Overprint"></a><code>-dOverprint=</code><em>/enable | /disable | /simulate</em></dt> -<dd> -This option provides control of overprinting. The default setting is <em><b>/enable</b></em> -which allows devices such as CMYK that can support overprint to leave planes unchanged -under control of PostScript and PDF overprint settings. -<p> -The <em><b>/disable</b></em> setting ignores all overprint (and overprint mode) from the input. -<p> -If <em><b>/simulate</b></em> is set, then pages with overprint (or overprint mode) set for -CMYK or Separation colors will be internally maintained and output to RGB or Gray -devices. -<p> -Note that not all spot color overprint cases can be accurately simulated with a CMYK -only device. For example, a case where you have a spot color overprinted with CMYK -colors will be indistiguishable from a case where you have spot color equivalent -CMYK colorants overprinted with CMYK colors, even though they may need to show -significantly different overprint simulations. To obtain a full overprint simulation, -use the <em><b>/simulate</b></em> setting or the psdcmyk or tiffsep device, where the spot -colors are kept in their own individual planes.</dd> -</dl> - -<dl> - <dt><code>-dUsePDFX3Profile=</code><em>int</em></dt> -<dd> -This option enables rendering with an output intent defined in -the PDF source file. If this option is included in the command line, -source device color values (e.g DeviceCMYK, DeviceRGB, or DeviceGray) -that match the color model of the output intent will be interpreted to -be in the output intent color space. In addition, if the output device -color model matches the output intent color model, then the -destination ICC profile will be the output intent ICC profile. - -If there is a mismatch between the device color model and the -output intent, the output intent profile will be used as a -proofing profile, since that is the intended rendering. - -Note that a PDF document can have multiple -rendering intents per the PDF specification. As such, with -the option -dUsePDFX3Profile the first output intent -encountered will be used. It is possible to specify -a particular output intent where <em>int</em> is an -integer (a value of 0 is the same as not specifying a number). -Probing of the output intents for a particular file -is possible using extractICCprofiles.ps in ./gs/toolbin. - -Finally, note that the ICC profile member entry is an option in -the output intent dictionary. In these cases, the output intent -specifies a registry and a standard profile (e.g. Fogra39). Ghostscript will -not make use of these output intents. Instead, if desired, these standard - profiles should be used with the commands specified above (e.g. -sOutputICCProfile).</dd> -</dl> - -<dl> - <dt><code>-sUseOutputIntent=</code><em>string</em></dt> -<dd>Like <code>UsePDFX3Profile</code> above, this option enables rendering with an output intent defined in the - PDF source file. -<p> -This option behaves the same way as the <code>UsePDFX3Profile</code>, but the selection criteria are different. -Because its possible (as of PDF 2.0) for each page to have a different array, its not sufficient just to supply -an array index, as the same profile might potentially be at different indices in each array.</p> -<p> -Instead this option takes a string, which is first compared against the <code>OutputConditionIdentifier</code> -in each OutputIntent in the array. If the <code>OutputConditionIdentifier</code> is not a standard identifier -then it should be Custom and the <code>UseOutputIntent</code> string will be matched against the value of the -<code>Info</code> key instead. If the <code>OutputConditionIdentifier</code> or <code>Info</code> matches the -value of <code>UseOuttpuIntent</code>, then that OutputIntent is selected <b>if</b> the OutputIntent contains -a <code>DestOutputProfile</code> key.</p> -</dd> -</dl> - -<dl> - <dt><code>-sICCProfilesDir=</code><em>path</em></dt> -<dd>Set a directory in which to search for the above profiles. - The directory path must end with a file system delimiter. -<p> -If the user doesn't use the -sICCProfilesDir= command line option, -Ghostscript creates a default value for it by looking on the -directory paths explained in <a href="#Finding_files">How -Ghostscript finds files</a>. If the current directory is the first -path a test is made for the iccprofiles directory. Next, the remaining -paths with the string Resource in it are tested. The prefix up to -the path separator character preceding the string Resource, concatenated -with the string iccprofiles is used and if this exists, then this -path will be used for ICCProfilesDir.</p> -<p> -Note that if the build is performed with COMPILE_INITS=1, -then the profiles contained in gs/iccprofiles will be placed in -the ROM file system. If a directory is specified on the command -line using -sICCProfilesDir=, that directory is searched before -the iccprofiles/ directory of the ROM file system is searched.</p> -<p> -<b><font size="+1"> -A note for Windows users, Artifex recommends the use of the -forward slash delimiter due to the special interpretation of \" by -the Microsoft C startup code. See -<a href="http://msdn.microsoft.com/en-us/library/a1y7w461.aspx">Parsing C Command-Line Arguments</a> -for more information. -</font></b></p> -</dd> -</dl> - -<h4><a name="Other_parameters"></a>Other parameters</h4> - -<dl> -<dt><code>-dFILTERIMAGE</code></dt> -<dd>If set, ths will ignore all images in the input (in this context image means a bitmap), these will -therefore not be rendered.</dd> -</dl> - -<dl> -<dt><code>-dFILTERTEXT</code></dt> -<dd>If set, ths will ignore all text in the input (just because it looks like text doesn't mean it is, it might be an image), text will -therefore not be rendered.</dd> -</dl> - -<dl> -<dt><code>-dFILTERVECTOR</code></dt> -<dd>If set, ths will ignore anything whch is neither text nor an image..</dd> -</dl> - -<dl> - <dt><code>-dDELAYBIND</code></dt> -<dd>Causes <code>bind</code> to remember all its invocations, but not -actually execute them until the <code>.bindnow</code> procedure is -called. Useful only for certain specialized packages like -<code>pstotext</code> that redefine operators. See the documentation -for <a href="Language.htm#bindnow"><code>.bindnow</code></a> for more information - on using this feature.</dd> -</dl> - -<dl> - <dt><code>-dDOPDFMARKS</code></dt> -<dd>Causes <code>pdfmark</code> to be called for bookmarks, -annotations, links and cropbox when processing PDF files. -Normally, <code>pdfmark</code> is only called for these types -for PostScript files or when the output device requests it - (e.g. pdfwrite device).</dd> -</dl> - -<dl> - <dt><code>-dJOBSERVER</code></dt> -<dd>Define <code>\004 (^D)</code> to start a new encapsulated job used for -compatibility with Adobe PS Interpreters that ordinarily run under a job -server. The <code>-dNOOUTERSAVE</code> switch is ignored if <code>-dJOBSERVER</code> -is specified since job servers <b>always</b> execute the input PostScript -under a save level, although the <code>exitserver</code> operator can -be used to escape from the encapsulated job and execute as if the - <code>-dNOOUTERSAVE</code> was specified. -<p> -This also requires that the input be from stdin, otherwise an error will -result (<code>Error: /invalidrestore in --restore--</code>).</p> -<p>Example usage is: -<pre> - gs ... -dJOBSERVER - < inputfile.ps - -or- - cat inputfile.ps | gs ... -dJOBSERVER - -</pre> -<b>Note: </b>The <code>^D</code> does not result in an end-of-file action -on stdin as it may on some PostScript printers that rely on TBCP (Tagged -Binary Communication Protocol) to cause an out-of-band <code>^D</code> to -signal EOF in a stream input data. This means that direct file actions -on stdin such as <code>flushfile</code> and <code>closefile</code> -will affect processing of data beyond the <code>^D</code> in the stream.</p> -</dd> -</dl> - -<dl> - <dt><code>-dNOCACHE</code></dt> - <dd>Disables character caching. Useful only for debugging.</dd> -</dl> - -<dl> - <dt><code>-dNOGC</code></dt> -<dd>Suppresses the initial automatic enabling of the garbage collector in -Level 2 systems. (The <code>vmreclaim</code> operator is not disabled.) - Useful only for debugging.</dd> -</dl> - -<dl> - <dt><code>-dNOOUTERSAVE</code></dt> -<dd>Suppresses the initial save that is used for compatibility with Adobe -PS Interpreters that ordinarily run under a job server. If a job server is -going to be used to set up the outermost save level, then <code>-dNOOUTERSAVE</code> -should be used so that the restore between jobs will restore global VM as - expected.</dd> -</dl> - -<a name="NoSafer"></a> -<dl> - <dt><code>-dNOSAFER</code> (equivalent to <code>-dDELAYSAFER</code>).</dt> -<dd>This flag disables SAFER mode until the <code>.setsafe</code> -procedure is run. This is intended for clients or scripts that cannot -operate in SAFER mode. If Ghostscript is started with <code>-dNOSAFER</code> -or <code>-dDELAYSAFER</code>, PostScript programs are allowed to read, write, -rename or delete any files in the system that are not protected by operating -system permissions. -<p><b>This mode should be used with caution, and <code>.setsafe</code> should be - run prior to running any PostScript file with unknown contents.</b></p> - - </dd> -</dl> -<a name="Safer"></a> -<dl> - <dt><code>-dSAFER</code></dt> -<dd> -<strong>IMPORTANT NOTE:</strong> Ghostscript now (as of 9.50) defaults to SAFER being active. -<p> -Enables access controls on files. Access controls fall into three categories, -files from which Ghostscript is permitted to read, ones to which it is permitted -to write, and ones over which it has "control" (i.e. delete/rename). These -access controls apply to <strong>all</strong> files accessed via Ghostscript's internal -interface to the C library file handling. Whilst we have taken considerable pains to -ensure that all the code we maintain (as well as the so called "contrib" devices, -that are devices included in our release packages, but not strictly maintained by the -Ghostscript development team) uses this interface, we have no control over thirdparty -code. -<p> -This is an entirely new implementation of <code>SAFER</code> for Ghostscript versions -9.50 and later. Earlier versions (see "<a href="#OldSafer">-dOLDSAFER</a>") relied on -storing the file permission lists in Postscript VM (Virtual Memory), and only applied -file access permissions to the Postscript file related operators. It relied on restricting -the function of <code>setpagedevice</code> to avoid the device code from being manipulated -into opening arbitrary files. The application of the file permissions was done within the -internal context of the Postscript interpreter, and some other aspects of the Postscript -restrictions were applied in the Postscript environment. With so many of the feature's -capabilities relying on the Postscript context and environment, by using other (Ghostscript -specific) features maliciously, the restrictions could be overridden. -<p> -Whilst the path storage and application of the permissions is implemented entirely in C, -it is still possible for Postscript to add and remove paths from the permissions lists -(see <a href="Language.htm#.addcontrolpath">.addcontrolpath</a>) until such time as the -access controls are enabled (see <a href="Language.htm#.activatepathcontrol">.activatepathcontrol</a>), -any call to <code>.addcontrolpath</code> after <code>.activatepathcontrol</code> will result in a -<code>Fatal</code> error causing the interpreter to immediately exit. -<p> -An incompatibility exists between the pre-9.50 and 9.50 and later <code>SAFER</code>. -By removing storage and application entirely from the Postscript language -environment and internal context, SAFER is no longer affected by Postscript -<code>save</code>/<code>restore</code> operations. Previously, it was possible -to do the equivalent of: -<blockquote> -<br><code>save</code> -<br><code>.setsafe</code> -<br><code>Postscript ops</code> -<br><code>restore</code> -</blockquote> -<p> -In that sequence, the <code>Postscript ops</code> would run with <code>SAFER</code> protection -but after the restore, <code>SAFER</code> would no longer be in force. This is no longer the case. -After the call to <code>.setsafe</code> the file controls are in force until the -interpreter exits. As the 9.50 and later implementation no longer restricts the -operation of <code>setpagedevice</code>, and because this capability is <i>extremely</i> -rarely used, we feel the improvement in security warrants the small reduction in -flexibility. -<p> -Path matching is very simple: it is case sensitive, and we do not implement full featured -"globbing" or regular expression matching (such complexity would significantly -and negatively impact performance). Further, the string parameter(s) passed to the -<code>--permit-file-*</code> option must exactly match the string(s) used to reference -the file(s): for example, you cannot use a absolute path to grant permission, and -then a relative path to reference the file (or vice versa) - the path match will fail. -Similarly, you cannot grant permission through one symlink, and then reference a file -directly, or through an alternative symlink - again, the matching will fail. -<p> -The following cases are handled: -<ul> -<li> -<dl><dt></dt><dd><code>"/path/to/file"</code></dd></dl> -<p>Permits access only to the file: "/path/to/file" -</li> -<li> -<dl><dt></dt><dd><code>"/path/to/directory/"</code></dd></dl> -<p>Permits access to any file in, and only in, the directory: "/path/to/directory" -</li> -<li> -<dl><dt></dt><dd><code>"/path/to/directory/*"</code></dd></dl> -<p>Permits access to any file in the directory: "/path/to/directory" and -any child of that directory. -</li> -</ul> -<p><strong>Important Note for Windows Users</strong>: -<br> -The file/path pattern matching is case sensitive, even on Windows. This is a -change in behaviour compared to the old code which, on Windows, was case -<i>in</i>sensitive. This is in recognition of changes in Windows behaviour, -in that it now supports (although does not enforce) case sensitivity. -<p> -Four command line parameters permit explicit control of the paths included in -the access control lists: -<ul> -<li><dl><dt></dt><dd><code>--permit-file-read=<em>pathlist</em></code></dd></dl> -<p> Adds a path, or list of paths, to the "permit read" list. A list -of paths is a series of paths separated by the appropriate path list separator -for your platform (for example, on Unix-like systems it is ":" -and on MS Windows it is ";"). -</li> -<li><dl><dt></dt><dd><code>--permit-file-write=<em>pathlist</em></code></dd></dl> -<p> Adds a path, or list of paths, to the "permit write" list. A list -of paths is a series of paths separated by the appropriate path list separator -for your platform (for example, on Unix-like systems it is ":" -and on MS Windows it is ";"). -</li> -<li><dl><dt></dt><dd><code>--permit-file-control=<em>pathlist</em></code></dd></dl> -<p> Adds a path, or list of paths, to the "permit control" list. A list -of paths is a series of paths separated by the appropriate path list separator -for your platform (for example, on Unix-like systems it is ":" -and on MS Windows it is ";"). -</li> -<li><dl><dt></dt><dd><code>--permit-file-all=<em>pathlist</em></code></dd></dl> -<p> Adds a path, or list of paths, to the all the above lists. A list -of paths is a series of paths separated by the appropriate path list separator -for your platform (for example, on Unix-like systems it is ":" -and on MS Windows it is ";"). -</li> -</ul> -<p> -'*' may be used as a wildcard in the above paths to mean "any -character other than the directory separator. Do not use two -or more *'s without intervening characters. -<p> -Finally, paths supplied on the command line (such as those in <code>-I</code>, -<code>-sFONTPATH</code> parameters) are added to the permitted reading list. -Similarly, paths read during initialisation from <code>Fontmap</code>, <code>cidfmap</code>, -and the platform specific font file enumeration (e.g. <code>fontconfig</code> on Unix systems) -are automatically added to the permit read lists. -</dd> -</dl> -<br> -<a name="OldSafer"></a> -<dl> - <dt><code>-dOLDSAFER</code></dt> -<dd> -<strong>NOTE: This enables deprecated code which will shortly be removed</strong> -<p>Used in combination with <code>-dSAFER</code> (or <code>.setsafe</code>) enables -the pre-9.50 SAFER implementation. It is included (for now) in case any users find -a case where the 9.50 and later <code>SAFER</code> does not work for them. It means -such users can keep working until we have assessed the issue, and distributed a solution. -<p> -Disables the <code>deletefile</code> and <code>renamefile</code> -operators, and the ability to open piped commands (<code>%pipe%</code><em>cmd</em>) -at all. Only <code>%stdout</code> and <code>%stderr</code> can be opened -for writing. Disables reading of files other than <code>%stdin</code>, -those given as a command line argument, or those contained on one of the paths -given by LIBPATH and FONTPATH and specified by the system params /FontResourceDir -and /GenericResourceDir. -<p> -This mode also sets the <a href="Language.htm#LockSafetyParams">.LockSafetyParams</a> -parameter of the default device, or the device specified with the <code>-sDEVICE= </code> -switch to protect against programs that attempt to write to files using the -OutputFile device parameter. Note that since the device parameters specified -on the command line (including OutputFile) are set prior to SAFER mode, -the <code>-sOutputFile=...</code> on the command line is unrestricted.</p> -<p> -SAFER mode also prevents changing the /GenericResourceDir, /FontResourceDir -and either the /SystemParamsPassword or the /StartJobPassword.</p> -<p> -When running -dNOSAFER it is possible to perform a <code>save</code>, -followed by <code>.setsafe</code>, execute a file or procedure in SAFER mode, -then use <code>restore</code> to return to NOSAFER mode. It is possible that the -a crafted foreign file could restore back to a point when NOSAFER was in operation.</p> -</dd> -</dl> - -<dl> - <dt><code>-dPreBandThreshold=true/false</code></dt> -<dd>If the target device is a halftone device, then images that are -normally stored in the command list during banded output will be halftoned during -the command list writing phase, if the resulting image will result in a smaller -command list. The decision to halftone depends upon the output and source resolution as well as - the output and source color space.</dd> -</dl> - -<dl> - <dt><code>-dWRITESYSTEMDICT</code></dt> -<dd>Leaves <code>systemdict</code> writable. This is necessary when -running special utility programs such as <code>font2c</code> and -<code>pcharstr</code>, which must bypass normal PostScript access - protection.</dd> -</dl> - -<hr> - -<h2><a name="Improving_performance"></a>Improving performance</h2> - -<p> -Ghostscript attempts to find an optimum balance between speed and memory -consumption, but there are some cases in which you may get a very large -speedup by telling Ghostscript to use more memory.</p> - -<p>Please note that this discussion relates to devices which produce a bitmap format as the output. -These parameters have no effect on the vector devices, such as pdfwrite.</p> - -<ul> -<li> -For raster printers and image format (jpeg*, tiff*, png* ...) devices, -performance can be 'tuned' by adjusting some of the parameters related -to banding (clist) options (refer to: <a href="Language.htm#Banding_parameters"> -Banding Parameters</a>).</li> -<li> -<p> -All devices may use a display list ("clist") and use banding when rendering -PDF 1.4 transparency. This prevents allocation of excessively large amounts of -memory for the transparency buffer stack. The <code>-dMaxBitmap=</code> option -is used to control when to use the display list, and the other banding parameters -mentioned above control the band size.</p> - -<p>In general, page buffer mode is faster than banded/clist mode (a full page -buffer is used when <code>-dMaxBitmap=#</code> is large enough for the entire -raster image) since there is no need to write, then interpret the clist data.</p> - -<p>On a multi-core system where multiple threads can be dispatched to -individual processors/cores, banding mode may provide higher performance -since <code>-dNumRenderingThreads=#</code> can be used to take advantage of -more than one CPU core when rendering the clist. The number of threads should -generally be set to the number of available processor cores for best throughput.</p> - -<p>In general, larger <code>-dBufferSpace=#</code> values provide -slightly higher performance since the per-band overhead is reduced.</p> -</li> -<li> -If you are using X Windows, setting the <code>-dMaxBitmap=</code> -parameter described <a href="#X_device_parameters">above</a> may -dramatically improve performance on files that have a lot of bitmap images.</li> - -<li> -With some PDF files, or if you are using Chinese, Japanese, or other fonts with -very large character sets, adding the following sequence of switches before the -first file name may dramatically improve performance at the cost of an additional -memory. For example, to allow use of 30Mb of extra RAM use: - - <code>-c 30000000 setvmthreshold -f</code>. -<p>This can also be useful in processing large documents when using a -high-level (vector) output device (like pdfwrite) that maintains significant internal -state.</p></li> - -<li> -<p> -For pattern tiles that are very large, Ghostscript uses an internal display -list (memory based clist), but this can slow things down. The current default -threshold is 8Mb -- pattern tiles larger than this will be cached as clist -rather than bitmap tiles. The parameter <code>-dMaxPatternBitmap=#</code> can -be used to adjust this threshold, smaller to reduce memory requirements and - larger to avoid performance impacts due to clist based pattern handling.</p> -<p> -For example, <code>-dMaxPatternBitmap=200000</code> will use clist based - patterns for pattern tiles larger than 200,000 bytes.</p></li> -</ul> -<hr> -<h2><a name="Environment_variables"></a>Summary of environment variables</h2> - -<dl> - <dt><code>GS</code>, <code>GSC</code> (MS Windows only)</dt> -<dd>Specify the names of the Ghostscript executables. <code>GS</code> -brings up a new typein window and possibly a graphics window; -<code>GSC</code> uses the DOS console. If these are not set, -<code>GS</code> defaults to <code>gswin32</code>, and - <code>GSC</code> defaults to <code>gswin32c</code>.</dd> -</dl> - -<dl> - <dt><a href="#GS_DEVICE"><code>GS_DEVICE</code></a></dt> -<dd>Defines the default output device. This overrides the compiled-in default, but is overridden by any commandline setting.</dd> -</dl> - -<dl> - <dt><a href="#Font_lookup"><code>GS_FONTPATH</code></a></dt> -<dd>Specifies a list of directories to scan for fonts if a font requested - can't be found anywhere on the search path.</dd> -</dl> - -<dl> - <dt><a href="#Finding_files"><code>GS_LIB</code></a></dt> - <dd>Provides a search path for initialization files and fonts.</dd> -</dl> - -<dl> - <dt><code>GS_OPTIONS</code></dt> -<dd>Defines a list of command-line arguments to be processed before the -ones actually specified on the command line. For example, setting -<code>GS_DEVICE</code> to XYZ is equivalent to setting -<code>GS_OPTIONS</code> to <code>-sDEVICE=XYZ</code>. The contents -of <code>GS_OPTIONS</code> are not limited to switches; they may include - actual file names or even <a href="#Input_control">"@file" arguments</a>.</dd> - -</dl> - -<dl> - <dt><a href="#Temp_files"><code>TEMP</code>, <code>TMPDIR</code></a></dt> -<dd>Defines a directory name for temporary files. If both -<code>TEMP</code> and <code>TMPDIR</code> are defined, - <code>TMPDIR</code> takes precedence.</dd> -</dl> - -<hr> - -<h2><a name="Debugging"></a>Debugging</h2> - -<p> -The information here describing is probably interesting only to developers.</p> - -<h3><a name="Debug_switches"></a>Debug switches</h3> - -<p>There are several debugging switches that are detected by the interpreter. -These switches are available whether or not Ghostscript was built with the -DEBUG macro defined to the compiler (refer to <a href="Make.htm#Debugging"> -building a debugging configuration</a>).</p> - -<p>Previous to 8.10, there was a single DEBUG flag, enabled with <code>-dDEBUG -</code> on the command line. Now there are several debugging flags to allow -more selective debugging information to be printed containing only what is -needed to investigate particular areas. For backward compatibilty, the -<code>-dDEBUG</code> option will set all of the subset switches.</p> - -<table> - <tr><td><code>-dCCFONTDEBUG</code></td><td>Compiled Fonts</td></tr> - <tr><td><code>-dCFFDEBUG</code></td><td>CFF Fonts</td></tr> - <tr><td><code>-dCMAPDEBUG</code></td><td>CMAP</td></tr> - <tr><td><code>-dDOCIEDEBUG</code></td><td>CIE color</td></tr> - <tr><td><code>-dEPSDEBUG</code></td><td>EPS handling</td></tr> - <tr><td><code>-dFAPIDEBUG</code></td><td>Font API</td></tr> - <tr><td><code>-dINITDEBUG</code></td><td>Initialization</td></tr> - <tr><td><code>-dPDFDEBUG</code></td><td>PDF Interpreter</td></tr> - <tr><td><code>-dPDFWRDEBUG</code></td><td>PDF Writer</td></tr> - <tr><td><code>-dSETPDDEBUG</code></td><td>setpagedevice</td></tr> - <tr><td><code>-dSTRESDEBUG</code></td><td>Static Resources</td></tr> - <tr><td><code>-dTTFDEBUG</code></td><td>TTF Fonts</td></tr> - <tr><td><code>-dVGIFDEBUG</code></td><td>ViewGIF</td></tr> - <tr><td><code>-dVJPGDEBUG</code></td><td>ViewJPEG</td></tr> -</table> - -<p> -The PDF interpreter normally tries to repair, or ignore, all problems encountered in PDF files. -Setting <code>-dPDFSTOPONERROR</code> instead causes the interpreter to signal an error and -stop processing the PDF file, instead of printing a warning. -</p><p> -The <code>-dPDFSTOPONWARNING</code> switch behaves the same, but will stop if a condition -which would normally merit a warning (instead of an error) is encountered. Note that -setting <code>-dPDFSTOPONWARNING</code> also sets <code>-dPDFSTOPONERROR</code>. -</p> - -<p> -The <code>-Z</code> and <code>-T</code> switches apply only -if the interpreter was <a href="Make.htm#Debugging">built for a debugging -configuration</a>. In the table below, the first column is a debugging -switch, the second is an equivalent switch (if any) and the third is its -usage.</p> - -<blockquote> -<table> - <tr><th colspan="2">Switches used in debugging</th></tr> - <tr> <th align="left">Switch</th> - - - - <th align="left"> Description</th></tr> - <tr> <td valign="top"><code>-B</code><em>size</em></td> - - <td>Run all subsequent files named on the command line (except for - <code>-F</code>) through the run_string interface, using a - buffer of <em>size</em> bytes</td></tr> - <tr> <td valign="top"><code>-B-</code></td> - - <td>Turn off <code>-B</code>: run subsequent files (except for - <code>-F</code>) directly in the normal way</td></tr> - <tr> <td valign="top"><code>-F</code><em>file</em></td> - - <td>Execute the file with <code>-B1</code> temporarily in effect</td></tr> - <tr> <td valign="top"><code>-K</code><em>n</em></td> - - <td>Limit the total amount of memory that the interpreter can have - allocated at any one time to <b><em>n</em></b>K bytes. - <b><em>n</em></b> is a positive decimal integer.</td></tr> - <tr> <td valign="top"><code>-M</code><em>n</em></td> - - <td>Force the interpreter's allocator to acquire additional memory - in units of <b><em>n</em></b>K bytes, rather than the default - 20K. <b><em>n</em></b> is a positive decimal integer, on - 16-bit systems no greater than 63.</td></tr> -<tr> <td valign="top"><code>-N</code><em>n</em></td> - - <td>Allocate space for <b><em>n</em></b>K names, rather than the - default (normally 64K). <b><em>n</em></b> may be greater than - 64 only if <code>EXTEND_NAMES</code> was defined (in - inameidx.h) when the interpreter was compiled .</td></tr> -<tr> <td valign="top"><code>-Z</code><em>xxx</em><br><code>-Z-</code><em>xxx</em></td> - - <td>Turn debugging printout on (off). Each of the <em>xxx</em> - characters selects an option. Case is significant: "a" and - "A" have different meanings.</td></tr> -</table> - -<dl compact> -<dt><code>0</code><dd>garbage collector, minimal detail</dd></dt> -<dt><code>1</code><dd>type 1 and type 42 font interpreter</dd></dt> -<dt><code>2</code><dd>curve subdivider/rasterizer</dd></dt> -<dt> <code>3</code><dd>curve subdivider/rasterizer, detail</dd></dt> -<dt><code>4</code><dd>garbage collector (strings)</dd></dt> -<dt> <code>5</code><dd>garbage collector (strings, detail)</dd></dt> -<dt><code>6</code><dd>garbage collector (clumps, roots)</dd></dt> -<dt> <code>7</code><dd>garbage collector (objects)</dd></dt> -<dt> <code>8</code><dd>garbage collector (refs)</dd></dt> -<dt> <code>9</code><dd>garbage collector (pointers)</dd></dt> -<dt><code>a</code><dd>allocator (large blocks only)</dd></dt> -<dt> <code>A</code><dd>allocator (all calls)</dd></dt> -<dt><code>b</code><dd>bitmap image processor</dd></dt> -<dt> <code>B</code><dd>bitmap images, detail</dd></dt> -<dt><code>c</code><dd>color/halftone mapper</dd></dt> -<dt><code>d</code><dd>dictionary put/undef</dd></dt> -<dt> <code>D</code><dd>dictionary lookups</dd></dt> -<dt><code>e</code><dd>external (OS-related) calls</dd></dt> -<dt><code>f</code><dd>fill algorithm (summary)</dd></dt> -<dt> <code>F</code><dd>fill algorithm (detail)</dd></dt> -<dt><code>g</code><dd>gsave/grestore[all]</dd></dt> -<dt><code>h</code><dd>halftone renderer</dd></dt> -<dt> <code>H</code><dd>halftones, every pixel</dd></dt> -<dt><code>i</code><dd>interpreter, just names</dd></dt> -<dt> <code>I</code><dd>interpreter, everything</dd></dt> -<dt><code>j</code><dd>(Japanese) composite fonts</dd></dt> -<dt><code>k</code><dd>character cache and xfonts</dd></dt> -<dt> <code>K</code><dd>character cache, every access</dd></dt> -<dt><code>l</code><dd>command lists, bands</dd></dt> -<dt> <code>L</code><dd>command lists, everything</dd></dt> -<dt><code>m</code><dd>makefont and font cache</dd></dt> -<dt><code>n</code><dd>name lookup (new names only)</dd></dt> -<dt><code>o</code><dd>outliner (stroke)</dd></dt> -<dt> <code>O</code><dd>stroke detail</dd></dt> -<dt><code>p</code><dd>band list paths</dd></dt> -<dt> <code>P</code><dd>all paths</dd></dt> -<dt><code>q</code><dd>clipping</dd></dt> -<dt><code>r</code><dd>arc renderer</dd></dt> -<dt><code>s</code><dd>streams</dd></dt> -<dt> <code>S</code><dd>scanner</dd></dt> -<dt><code>t</code><dd>tiling algorithm</dd></dt> -<dt><code>u</code><dd>undo saver (for save/restore), finalization</dd></dt> -<dt> <code>U</code><dd>undo saver, more detail</dd></dt> -<dt><code>v</code><dd>compositors: alpha/transparency/overprint/rop</dd></dt> -<dt> <code>V</code><dd>compositors: alpha/transparency/overprint/rop, more detail</dd></dt> -<dt><code>w</code><dd>compression encoder/decoder</dd></dt> -<dt><code>x</code><dd>transformations</dd></dt> -<dt><code>y</code><dd>Type 1 hints</dd></dt> -<dt> <code>Y</code><dd>Type 1 hints, every access</dd></dt> -<dt><code>z</code><dd>trapezoid fill</dd></dt> -<dt><code>#</code><dd>operator error returns</dd></dt> -<dt><code>%</code><dd>externally processed comments</dd></dt> -<dt><code>*</code><dd>image and RasterOp parameters</dd></dt> -<dt><code>:</code><dd>command list and allocator/time summary</dd></dt> -<dt><code>~</code><dd>math functions and Functions</dd></dt> -<dt><code>'</code><dd>contexts, create/destroy</dd></dt> -<dt> <code>"</code><dd>contexts, every operation</dd></dt> -<dt><code>^</code><dd>reference counting</dd></dt> -<dt><code>_</code><dd>high-level (vector) output</dd></dt> -<dt><code>!</code><dd>Postscript operator names (this option is available only when Ghostscript is compiled with a predefined macro DEBUG_TRACE_PS_OPERATORS)</dd></dt> -<dt><code>|</code><dd>(reserved for experimental code)</dd></dt> -</dl> - -<p> -The following switch affects what is printed, but does not select specific - items for printing:</p> - -<dl compact> - <dt><code>/</code><dd>include file name and line number on all trace output</dd></dt> -</dl> - -<p> - These switches select debugging options other than what should be printed:</p> - -<dl compact> -<dt><code>$</code><dd>set unused parts of object references to -identifiable garbage values</dd></dt> -<dt><code>+</code><dd>use minimum-size stack blocks</dd></dt> -<dt><code>,</code><dd>don't use path-based banding</dd></dt> -<dt><code>`</code><dd>don't use high-level banded images</dd></dt> -<dt><code>?</code><dd>validate pointers before, during and after garbage -collection, also before and after save and restore; also make other -allocator validity checks</dd></dt> -<dt><code>@</code><dd>fill newly allocated, garbage-collected, and freed -storage with a marker (a1, c1, and f1 respectively)</dd></dt> -</dl> - -<tr> <td valign="top"><code>-T</code><em>xxx</em><br><code>-T-</code><em>xxx</em></td> - <td> </td> - <td> </td> - <td> </td> - <td>Turn <a href="#Visual_trace">Visual Trace</a> on (off). Each of the <em>xxx</em> - characters selects an option. Case is significant: "f" and - "F" have different meanings.</td></tr> - -<dl compact> -<dt><code>f</code><dd>the filling algorithm with characters</dd></dt> -<dt><code>F</code><dd>the filling algorithm with non-character paths</dd></dt> -<dt><code>h</code><dd>the Type 1 hinter</dd></dt> -<dt><code>s</code><dd>the shading algorithm</dd></dt> -<dt><code>S</code><dd>the stroking algorithm</dd></dt> -</dl> -</blockquote> - -<p>In addition, calling ghostscript with <code>--debug</code> will list all the currently -defined (non visual trace) debugging flags, both in their short form (as listed -above for use with <code>-Z</code>) and in a long form, which can be used as in: -<code>--debug=tiling,alloc</code>. All the short form flags for <code>-Z</code> -have an equivalent long form. Future flags may be added with a long form only - (due to all the short form flags being used already).</p> - -<h4><a name="Visual_trace"></a>Visual Trace</h4> - -<p> -Visual Trace allows to view internal Ghostscript data in a graphical form -while execution of C code. Special -<a href="Lib.htm#Visual_trace">instructions</a> to be inserted into -C code for generating the output. Client application -rasterizes it into a window.</p> - -<p> -Currently the rasterization is implemented for Windows only, in clients -gswin32.exe and gswin32c.exe. They open Visual Trace window when graphical -debug output appears, <code>-T</code> <a href="#Debug_switches">switch</a> is set, -and Ghostscript was <a href="Make.htm#Debugging">built</a> with DEBUG option. -There are two important incompletenesses of the implementation :</p> - -<p> -1. The graphical output uses a hardcoded scale. An advanced client -would provide a scale option via user interface.</p> - -<p> -2. Breaks are not implemented in the client. If you need a step-by-step -view, you should use an interactive C debugger to delay execution at breakpoints.</p> - -<hr> - -<h2><a name="Known_paper_sizes"></a>Appendix: Paper sizes known to Ghostscript</h2> - -<p> -The paper sizes known to Ghostscript are defined at the beginning of the -initialization file <code>gs_statd.ps</code>; see the comments there for -more details about the definitions. The table here lists them by name and -size. <code>gs_statd.ps</code> defines their sizes exactly in points, -and the dimensions in inches (at 72 points per inch) and centimeters shown -in the table are derived from those, rounded to the nearest 0.1 unit. A -guide to international paper sizes can be found at</p> - -<blockquote> -<a href="http://www.edsebooks.com/paper/papersize.html">http://www.edsebooks.com/paper/papersize.html</a> -</blockquote> - -<table> -<tr><th colspan="14">Paper sizes known to Ghostscript</th></tr> -<tr><td colspan="14" align="center">U.S. standard</td></tr> -<tr> - <td></td> - <td></td> - <td colspan="3" align="center">Inches</td> - <td></td> - <td colspan="3" align="center">mm</td> - <td></td> - <td colspan="3" align="center">Points</td> - <td></td> - </tr> -<tr> - <td align="left">Name</td> - <td></td> - <td align="center">W</td> - <td align="center">×</td> - <td align="center">H</td> - <td></td> - <td align="center">W</td> - <td align="center">×</td> - <td align="center">H</td> - <td></td> - <td align="center">W</td> - <td align="center">×</td> - <td align="center">H</td> - <td></td> - </tr> -<tr> - <td>11x17</td> - <td></td> - <td align="right">11.0</td> - <td></td> - <td align="right">17.0</td> - <td></td> - <td align="right">279</td> - <td></td> - <td align="right">432</td> - <td></td> - <td align="right">792</td> - <td></td> - <td align="right">1224</td> - <td>11×17in portrait</td> - </tr> -<tr> - <td>ledger</td> - <td></td> - <td align="right">17.0</td> - <td></td> - <td align="right">11.0</td> - <td></td> - <td align="right">432</td> - <td></td> - <td align="right">279</td> - <td></td> - <td align="right">1224</td> - <td></td> - <td align="right">792</td> - <td>11×17in landscape</td> - </tr> -<tr> - <td>legal</td> - <td></td> - <td align="right">8.5</td> - <td></td> - <td align="right">14.0</td> - <td></td> - <td align="right">216</td> - <td></td> - <td align="right">356</td> - <td></td> - <td align="right">612</td> - <td></td> - <td align="right">1008</td> - <td></td> - </tr> -<tr> - <td>letter</td> - <td></td> - <td align="right">8.5</td> - <td></td> - <td align="right">11.0</td> - <td></td> - <td align="right">216</td> - <td></td> - <td align="right">279</td> - <td></td> - <td align="right">612</td> - <td></td> - <td align="right">792</td> - <td></td> - </tr> -<tr> - <td>lettersmall</td> - <td></td> - <td align="right">8.5</td> - <td></td> - <td align="right">11.0</td> - <td></td> - <td align="right">216</td> - <td></td> - <td align="right">279</td> - <td></td> - <td align="right">612</td> - <td></td> - <td align="right">792</td> - <td></td> - </tr> -<tr> - <td>archE</td> - <td></td> - <td align="right">36.0</td> - <td></td> - <td align="right">48.0</td> - <td></td> - <td align="right">914</td> - <td></td> - <td align="right">1219</td> - <td></td> - <td align="right">2592</td> - <td></td> - <td align="right">3456</td> - <td></td> - </tr> -<tr> - <td>archD</td> - <td></td> - <td align="right">24.0</td> - <td></td> - <td align="right">36.0</td> - <td></td> - <td align="right">610</td> - <td></td> - <td align="right">914</td> - <td></td> - <td align="right">1728</td> - <td></td> - <td align="right">2592</td> - <td></td> - </tr> -<tr> - <td>archC</td> - <td></td> - <td align="right">18.0</td> - <td></td> - <td align="right">24.0</td> - <td></td> - <td align="right">457</td> - <td></td> - <td align="right">610</td> - <td></td> - <td align="right">1296</td> - <td></td> - <td align="right">1728</td> - <td></td> - </tr> -<tr> - <td>archB</td> - <td></td> - <td align="right">12.0</td> - <td></td> - <td align="right">18.0</td> - <td></td> - <td align="right">305</td> - <td></td> - <td align="right">457</td> - <td></td> - <td align="right">864</td> - <td></td> - <td align="right">1296</td> - <td></td> - </tr> -<tr> - <td>archA</td> - <td></td> - <td align="right">9.0</td> - <td></td> - <td align="right">12.0</td> - <td></td> - <td align="right">229</td> - <td></td> - <td align="right">305</td> - <td></td> - <td align="right">648</td> - <td></td> - <td align="right">864</td> - <td></td> - </tr> -<tr> <td colspan="14"></td></tr> -<tr> <th colspan="14">ISO standard</th></tr> -<tr> <td colspan="14"></td></tr> -<tr> - <td>a0</td> - <td></td> - <td align="right">33.1</td> - <td></td> - <td align="right">46.8</td> - <td></td> - <td align="right">841</td> - <td></td> - <td align="right">1189</td> - <td></td> - <td align="right">2384</td> - <td></td> - <td align="right">3370</td> - <td></td> - </tr> -<tr> - <td>a1</td> - <td></td> - <td align="right">23.4</td> - <td></td> - <td align="right">33.1</td> - <td></td> - <td align="right">594</td> - <td></td> - <td align="right">841</td> - <td></td> - <td align="right">1684</td> - <td></td> - <td align="right">2384</td> - <td></td> - </tr> -<tr> - <td>2</td> - <td></td> - <td align="right">16.5</td> - <td></td> - <td align="right">23.4</td> - <td></td> - <td align="right">420</td> - <td></td> - <td align="right">594</td> - <td></td> - <td align="right">1191</td> - <td></td> - <td align="right">1684</td> - <td></td> - </tr> -<tr> - <td>a3</td> - <td></td> - <td align="right">11.7</td> - <td></td> - <td align="right">16.5</td> - <td></td> - <td align="right">297</td> - <td></td> - <td align="right">420</td> - <td></td> - <td align="right">842</td> - <td></td> - <td align="right">1191</td> - <td></td> - </tr> -<tr> - <td>a4</td> - <td></td> - <td align="right">8.3</td> - <td></td> - <td align="right">11.7</td> - <td></td> - <td align="right">210</td> - <td></td> - <td align="right">297</td> - <td></td> - <td align="right">595</td> - <td></td> - <td align="right">842</td> - <td></td> - </tr> -<tr> - <td>a4small</td> - <td></td> - <td align="right">8.3</td> - <td></td> - <td align="right">11.7</td> - <td></td> - <td align="right">210</td> - <td></td> - <td align="right">297</td> - <td></td> - <td align="right">595</td> - <td></td> - <td align="right">842</td> - <td></td> - </tr> -<tr> - <td>a5</td> - <td></td> - <td align="right">5.8</td> - <td></td> - <td align="right">8.3</td> - <td></td> - <td align="right">148</td> - <td></td> - <td align="right">210</td> - <td></td> - <td align="right">420</td> - <td></td> - <td align="right">595</td> - <td></td> - </tr> -<tr> - <td>a6</td> - <td></td> - <td align="right">4.1</td> - <td></td> - <td align="right">5.8</td> - <td></td> - <td align="right">105</td> - <td></td> - <td align="right">148</td> - <td></td> - <td align="right">297</td> - <td></td> - <td align="right">420</td> - <td></td> - </tr> -<tr> - <td>a7</td> - <td></td> - <td align="right">2.9</td> - <td></td> - <td align="right">4.1</td> - <td></td> - <td align="right">74</td> - <td></td> - <td align="right">105</td> - <td></td> - <td align="right">210</td> - <td></td> - <td align="right">297</td> - <td></td> - </tr> -<tr> - <td>a8</td> - <td></td> - <td align="right">2.1</td> - <td></td> - <td align="right">2.9</td> - <td></td> - <td align="right">52</td> - <td></td> - <td align="right">74</td> - <td></td> - <td align="right">148</td> - <td></td> - <td align="right">210</td> - <td></td> - </tr> -<tr> - <td>a9</td> - <td></td> - <td align="right">1.5</td> - <td></td> - <td align="right">2.1</td> - <td></td> - <td align="right">37</td> - <td></td> - <td align="right">52</td> - <td></td> - <td align="right">105</td> - <td></td> - <td align="right">148</td> - <td></td> - </tr> -<tr> - <td>a10</td> - <td></td> - <td align="right">1.0</td> - <td></td> - <td align="right">1.5</td> - <td></td> - <td align="right">26</td> - <td></td> - <td align="right">37</td> - <td></td> - <td align="right">73</td> - <td></td> - <td align="right">105</td> - <td></td> - </tr> -<tr> - <td>isob0</td> - <td> </td> - <td align="right">39.4</td> - <td> </td> - <td align="right">55.7</td> - <td> </td> - <td align="right">1000</td> - <td> </td> - <td align="right">1414</td> - <td> </td> - <td align="right">2835</td> - <td> </td> - <td align="right">4008</td> - <td></td> - </tr> -<tr> - <td>isob1</td> - <td></td> - <td align="right">27.8</td> - <td></td> - <td align="right">39.4</td> - <td></td> - <td align="right">707</td> - <td></td> - <td align="right">1000</td> - <td></td> - <td align="right">2004</td> - <td></td> - <td align="right">2835</td> - <td></td> - </tr> -<tr> - <td>isob2</td> - <td></td> - <td align="right">19.7</td> - <td></td> - <td align="right">27.8</td> - <td></td> - <td align="right">500</td> - <td></td> - <td align="right">707</td> - <td></td> - <td align="right">1417</td> - <td></td> - <td align="right">2004</td> - <td></td> - </tr> -<tr> - <td>isob3</td> - <td></td> - <td align="right">13.9</td> - <td></td> - <td align="right">19.7</td> - <td></td> - <td align="right">353</td> - <td></td> - <td align="right">500</td> - <td></td> - <td align="right">1001</td> - <td></td> - <td align="right">1417</td> - <td></td> - </tr> -<tr> - <td>isob4</td> - <td></td> - <td align="right">9.8</td> - <td></td> - <td align="right">13.9</td> - <td></td> - <td align="right">250</td> - <td></td> - <td align="right">353</td> - <td></td> - <td align="right">709</td> - <td></td> - <td align="right">1001</td> - <td></td> - </tr> -<tr> - <td>isob5</td> - <td></td> - <td align="right">6.9</td> - <td></td> - <td align="right">9.8</td> - <td></td> - <td align="right">176</td> - <td></td> - <td align="right">250</td> - <td></td> - <td align="right">499</td> - <td></td> - <td align="right">709</td> - <td></td> - </tr> -<tr> - <td>isob6</td> - <td></td> - <td align="right">4.9</td> - <td></td> - <td align="right">6.9</td> - <td></td> - <td align="right">125</td> - <td></td> - <td align="right">176</td> - <td></td> - <td align="right">354</td> - <td></td> - <td align="right">499</td> - <td></td> - </tr> -<tr> - <td>c0</td> - <td></td> - <td align="right">36.1</td> - <td></td> - <td align="right">51.1</td> - <td></td> - <td align="right">917</td> - <td></td> - <td align="right">1297</td> - <td></td> - <td align="right">2599</td> - <td></td> - <td align="right">3677</td> - <td></td> - </tr> -<tr> - <td>c1</td> - <td></td> - <td align="right">25.5</td> - <td></td> - <td align="right">36.1</td> - <td></td> - <td align="right">648</td> - <td></td> - <td align="right">917</td> - <td></td> - <td align="right">1837</td> - <td></td> - <td align="right">2599</td> - <td></td> - </tr> -<tr> - <td>c2</td> - <td></td> - <td align="right">18.0</td> - <td></td> - <td align="right">25.5</td> - <td></td> - <td align="right">458</td> - <td></td> - <td align="right">648</td> - <td></td> - <td align="right">1298</td> - <td></td> - <td align="right">1837</td> - <td></td> - </tr> -<tr> - <td>c3</td> - <td></td> - <td align="right">12.8</td> - <td></td> - <td align="right">18.0</td> - <td></td> - <td align="right">324</td> - <td></td> - <td align="right">458</td> - <td></td> - <td align="right">918</td> - <td></td> - <td align="right">1298</td> - <td></td> - </tr> -<tr> - <td>c4</td> - <td> </td> - <td align="right">9.0</td> - <td> </td> - <td align="right">12.8</td> - <td> </td> - <td align="right">229</td> - <td> </td> - <td align="right">324</td> - <td> </td> - <td align="right">649</td> - <td> </td> - <td align="right">918</td> - <td> </td> - <td> </td> -</tr> -<tr> - <td>c5</td> - <td></td> - <td align="right">6.4</td> - <td></td> - <td align="right">9.0</td> - <td></td> - <td align="right">162</td> - <td></td> - <td align="right">229</td> - <td></td> - <td align="right">459</td> - <td></td> - <td align="right">649</td> - <td></td> -</tr> -<tr> - <td>c6</td> - <td></td> - <td align="right">4.5</td> - <td></td> - <td align="right">6.4</td> - <td></td> - <td align="right">114</td> - <td></td> - <td align="right">162</td> - <td></td> - <td align="right">323</td> - <td></td> - <td align="right">459</td> - <td></td> -</tr> -<tr> - <td colspan="14"></td> -</tr> -<tr> - <th colspan="14">JIS standard</th> -</tr> -<tr> - <td colspan="14"></td> - </tr> -<tr> - <td>jisb0</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">1030</td> - <td></td> - <td align="right">1456</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td>jisb1</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">728</td> - <td></td> - <td align="right">1030</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td>jisb2</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">515</td> - <td></td> - <td align="right">728</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td>jisb</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">364</td> - <td></td> - <td align="right">515</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td>jisb4</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">257</td> - <td></td> - <td align="right">364</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td>jisb5</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">182</td> - <td></td> - <td align="right">257</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td>jisb6</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right">128</td> - <td></td> - <td align="right">182</td> - <td></td> - <td align="right"></td> - <td></td> - <td align="right"></td> - <td></td> - </tr> -<tr> - <td colspan="14"></td> - </tr> -<tr> - <th colspan="14">ISO/JIS switchable</th> - </tr> -<tr> - <td colspan="14"></td> - </tr> -<tr> <td colspan="14">b0 (see * below)</td></tr> -<tr> <td colspan="14">b1 (see * below)</td></tr> -<tr> <td colspan="14">b2 (see * below)</td></tr> -<tr> <td colspan="14">b3 (see * below)</td></tr> -<tr> <td colspan="14">b4 (see * below)</td></tr> -<tr> <td colspan="14">b5 (see * below)</td></tr> - -<tr> <td colspan="14" ></td></tr> -<tr> <th colspan="14">Other</th></tr> -<tr> <td colspan="14"></td></tr> -<tr> - <td>flsa</td> - <td></td> - <td align="right">8.5</td> - <td></td> - <td align="right">13.0</td> - <td></td> - <td align="right">216</td> - <td></td> - <td align="right">330</td> - <td></td> - <td align="right">612</td> - <td></td> - <td align="right">936</td> - <td>U.S. foolscap</td> - </tr> -<tr> - <td>flse</td> - <td></td> - <td align="right">8.5</td> - <td></td> - <td align="right">13.0</td> - <td></td> - <td align="right">216</td> - <td></td> - <td align="right">330</td> - <td></td> - <td align="right">612</td> - <td></td> - <td align="right">936</td> - <td>European foolscap</td> - </tr> -<tr> - <td>halfletter</td> - <td></td> - <td align="right">5.5</td> - <td></td> - <td align="right">8.5</td> - <td></td> - <td align="right">140</td> - <td></td> - <td align="right">216</td> - <td></td> - <td align="right">396</td> - <td></td> - <td align="right">612</td> - <td></td> - </tr> -<tr> - <td>hagaki</td> - <td></td> - <td align="right">3.9</td> - <td></td> - <td align="right">5.8</td> - <td></td> - <td align="right">100</td> - <td></td> - <td align="right">148</td> - <td></td> - <td align="right">283</td> - <td></td> - <td align="right">420</td> - <td>Japanese postcard</td> - </tr> -</table> - -<p> -*<em>Note:</em> Initially the B paper sizes are the ISO sizes, e.g., -<code>b0</code> is the same as <code>isob0</code>. Running the file -<code>lib/jispaper.ps</code> makes the B paper sizes be the JIS sizes, -e.g., <code>b0</code> becomes the same as <code>jisb0</code>.</p> - -<hr> - -<h2><a name="X_font_mappings"></a>Appendix: X default font mappings</h2> - -<h3><a name="Standard_X_server_fonts"></a>Standard X servers</h3> - -<h4><a name="X_regular_fonts"></a>Regular fonts</h4> - -<pre> - AvantGarde-Book: -Adobe-ITC Avant Garde Gothic-Book-R-Normal--\n\ - AvantGarde-BookOblique: -Adobe-ITC Avant Garde Gothic-Book-O-Normal--\n\ - AvantGarde-Demi: -Adobe-ITC Avant Garde Gothic-Demi-R-Normal--\n\ - AvantGarde-DemiOblique: -Adobe-ITC Avant Garde Gothic-Demi-O-Normal--\n\ - Bookman-Demi: -Adobe-ITC Bookman-Demi-R-Normal--\n\ - Bookman-DemiItalic: -Adobe-ITC Bookman-Demi-I-Normal--\n\ - Bookman-Light: -Adobe-ITC Bookman-Light-R-Normal--\n\ - Bookman-LightItalic: -Adobe-ITC Bookman-Light-I-Normal--\n\ - Courier: -Adobe-Courier-Medium-R-Normal--\n\ - Courier-Bold: -Adobe-Courier-Bold-R-Normal--\n\ - Courier-BoldOblique: -Adobe-Courier-Bold-O-Normal--\n\ - Courier-Oblique: -Adobe-Courier-Medium-O-Normal--\n\ - Helvetica: -Adobe-Helvetica-Medium-R-Normal--\n\ - Helvetica-Bold: -Adobe-Helvetica-Bold-R-Normal--\n\ - Helvetica-BoldOblique: -Adobe-Helvetica-Bold-O-Normal--\n\ - Helvetica-Narrow: -Adobe-Helvetica-Medium-R-Narrow--\n\ - Helvetica-Narrow-Bold: -Adobe-Helvetica-Bold-R-Narrow--\n\ - Helvetica-Narrow-BoldOblique: -Adobe-Helvetica-Bold-O-Narrow--\n\ - Helvetica-Narrow-Oblique: -Adobe-Helvetica-Medium-O-Narrow--\n\ - Helvetica-Oblique: -Adobe-Helvetica-Medium-O-Normal--\n\ - NewCenturySchlbk-Bold: -Adobe-New Century Schoolbook-Bold-R-Normal--\n\ - NewCenturySchlbk-BoldItalic: -Adobe-New Century Schoolbook-Bold-I-Normal--\n\ - NewCenturySchlbk-Italic: -Adobe-New Century Schoolbook-Medium-I-Normal--\n\ - NewCenturySchlbk-Roman: -Adobe-New Century Schoolbook-Medium-R-Normal--\n\ - Palatino-Bold: -Adobe-Palatino-Bold-R-Normal--\n\ - Palatino-BoldItalic: -Adobe-Palatino-Bold-I-Normal--\n\ - Palatino-Italic: -Adobe-Palatino-Medium-I-Normal--\n\ - Palatino-Roman: -Adobe-Palatino-Medium-R-Normal--\n\ - Times-Bold: -Adobe-Times-Bold-R-Normal--\n\ - Times-BoldItalic: -Adobe-Times-Bold-I-Normal--\n\ - Times-Italic: -Adobe-Times-Medium-I-Normal--\n\ - Times-Roman: -Adobe-Times-Medium-R-Normal--\n\ - ZapfChancery-MediumItalic: -Adobe-ITC Zapf Chancery-Medium-I-Normal-- -</pre> - -<h4><a name="X_symbol_fonts"></a>Symbol fonts</h4> - -<pre> Symbol: -Adobe-Symbol-Medium-R-Normal-- -</pre> - -<h4><a name="X_dingbat_fonts"></a>Dingbat fonts</h4> - -<pre> ZapfDingbats: -Adobe-ITC Zapf Dingbats-Medium-R-Normal-- -</pre> - -<h3><a name="OpenWindows_fonts"></a>Sun OpenWindows</h3> - -<p> -For Sun's X11/NeWS one can use the OpenWindows scalable fonts instead, -which gives good output for any point size. In this environment, the -relevant section of the resource file should look like this:</p> - -<pre>Ghostscript.regularFonts: \ - AvantGarde-Book: -itc-avantgarde-book-r-normal-- \n\ - AvantGarde-BookOblique: -itc-avantgarde-book-o-normal-- \n\ - AvantGarde-Demi: -itc-avantgarde-demi-r-normal-- \n\ - AvantGarde-DemiOblique: -itc-avantgarde-demi-o-normal-- \n\ - Bembo: -monotype-bembo-medium-r-normal-- \n\ - Bembo-Bold: -monotype-bembo-bold-r-normal-- \n\ - Bembo-BoldItalic: -monotype-bembo-bold-i-normal-- \n\ - Bembo-Italic: -monotype-bembo-medium-i-normal-- \n\ - Bookman-Demi: -itc-bookman-demi-r-normal-- \n\ - Bookman-DemiItalic: -itc-bookman-demi-i-normal-- \n\ - Bookman-Light: -itc-bookman-light-r-normal-- \n\ - Bookman-LightItalic: -itc-bookman-light-i-normal-- \n\ - Courier: -itc-courier-medium-r-normal-- \n\ - Courier-Bold: -itc-courier-bold-r-normal-- \n\ - Courier-BoldOblique: -itc-courier-bold-o-normal-- \n\ - Courier-Oblique: -itc-courier-medium-o-normal-- \n\ - GillSans: -monotype-gill-medium-r-normal-sans- \n\ - GillSans-Bold: -monotype-gill-bold-r-normal-sans- \n\ - GillSans-BoldItalic: -monotype-gill-bold-i-normal-sans- \n\ - GillSans-Italic: -monotype-gill-normal-i-normal-sans- \n\ - Helvetica: -linotype-helvetica-medium-r-normal-- \n\ - Helvetica-Bold: -linotype-helvetica-bold-r-normal-- \n\ - Helvetica-BoldOblique: -linotype-helvetica-bold-o-normal-- \n\ - Helvetica-Narrow: -linotype-helvetica-medium-r-narrow-- \n\ - Helvetica-Narrow-Bold: -linotype-helvetica-bold-r-narrow-- \n\ - Helvetica-Narrow-BoldOblique: -linotype-helvetica-bold-o-narrow-- \n\ - Helvetica-Narrow-Oblique: -linotype-helvetica-medium-o-narrow-- \n\ - Helvetica-Oblique: -linotype-helvetica-medium-o-normal-- \n\ - LucidaBright: -b&h-lucidabright-medium-r-normal-- \n\ - LucidaBright-Demi: -b&h-lucidabright-demibold-r-normal-- \n\ - LucidaBright-DemiItalic: -b&h-lucidabright-demibold-i-normal-- \n\ - LucidaBright-Italic: -b&h-lucidabright-medium-i-normal-- \n\ - LucidaSans: -b&h-lucida-medium-r-normal-sans- \n\ - LucidaSans-Bold: -b&h-lucida-bold-r-normal-sans- \n\ - LucidaSans-BoldItalic: -b&h-lucida-bold-i-normal-sans- \n\ - LucidaSans-Italic: -b&h-lucida-medium-i-normal-sans- \n\ - LucidaSans-Typewriter: -b&h-lucidatypewriter-medium-r-normal-sans- \n\ - LucidaSans-TypewriterBold: -b&h-lucidatypewriter-bold-r-normal-sans- \n\ - NewCenturySchlbk-BoldItalic: -linotype-new century schoolbook-bold-i-normal-- \n\ - NewCenturySchlbk-Bold: -linotype-new century schoolbook-bold-r-normal-- \n\ - NewCenturySchlbk-Italic: -linotype-new century schoolbook-medium-i-normal-- \n\ - NewCenturySchlbk-Roman: -linotype-new century schoolbook-medium-r-normal-- \n\ - Palatino-Bold: -linotype-palatino-bold-r-normal-- \n\ - Palatino-BoldItalic: -linotype-palatino-bold-i-normal-- \n\ - Palatino-Italic: -linotype-palatino-medium-i-normal-- \n\ - Palatino-Roman: -linotype-palatino-medium-r-normal-- \n\ - Rockwell: -monotype-rockwell-medium-r-normal-- \n\ - Rockwell-Bold: -monotype-rockwell-bold-r-normal-- \n\ - Rockwell-BoldItalic: -monotype-rockwell-bold-i-normal-- \n\ - Rockwell-Italic: -monotype-rockwell-medium-i-normal-- \n\ - Times-Bold: -linotype-times-bold-r-normal-- \n\ - Times-BoldItalic: -linotype-times-bold-i-normal-- \n\ - Times-Italic: -linotype-times-medium-i-normal-- \n\ - Times-Roman: -linotype-times-medium-r-normal-- \n\ - Utopia-Bold: -adobe-utopia-bold-r-normal-- \n\ - Utopia-BoldItalic: -adobe-utopia-bold-i-normal-- \n\ - Utopia-Italic: -adobe-utopia-regular-i-normal-- \n\ - Utopia-Regular: -adobe-utopia-regular-r-normal-- \n\ - ZapfChancery-MediumItalic: -itc-zapfchancery-medium-i-normal-- \n -Ghostscript.dingbatFonts: \ - ZapfDingbats: -itc-zapfdingbats-medium-r-normal-- -Ghostscript.symbolFonts: \ - Symbol: --symbol-medium-r-normal-- -</pre> - -<hr> -<h2><a name="FAPI_run"></a>Running Ghostscript with third-party font renderers</h2> - -<p> -Font API (FAPI) is a feature which allows to attach third-party font -renderers to Ghostscript. -This section explains how to run Ghostscript with third-party font -renderers, such as UFST. NOTE: FreeType is now the default font renderer -for Ghostscript.</p> - -<p> -<em>Note: To run Ghostscript with UFST you need a license from Monotype Imaging. -Please ignore issues about UFST if you haven't got it. -</em></p> - -<p> -<em> -Important note: Third-party font renderers may be incompatible -with devices that can embed fonts in their output (such as pdfwrite), -because such renderers may store fonts in a form from which Ghostscript cannot -get the necessary information for embedding, for example, the Microtype fonts supplied -with the UFST. Ghostscript can be configured to disable such renderers when such a -device is being used. -</em></p> - -<p> -As of Ghostscript version 9.0, Ghostscript uses Freetype 2.4.x as the default font -scaler/renderer.</p> - -<p>With this change, we added a new switch:<code>-dDisableFAPI=true</code> to revert to the older -behavior, just in case serious regression happens that cannot be resolved in a timely manner. -It is intended that this switch will be removed once the FAPI/Freetype implementation has -proven itself robust and reliable in the "real world".</p> - -<p> -<em> -NOTE: With version 9.18 recently released we have, for some time, regarded FAPI/Freetype as being -the canonical glyph rendering solution for Ghostscript and associated products, and the non-FAPI -rendering to be deprecated. As such, the <code>-dDisableFAPI=true</code> option is also considered -deprecated, and should be expected to be removed shortly after the next release. -</em> -</p> - -<p> -To run Ghostscript with UFST, you first need to build Ghostscript -with the UFST bridge. Refer <a href="Make.htm#UFST_build">How to build Ghostscript with UFST</a>. -Both bridges may run together.</p> - -<p> -There are 2 ways to handle fonts with a third-party font renderer (FAPI). -First, you can substitute -any FAPI-handled font to a resident PostScript font, using special map files -<code>FAPIfontmap</code> and <code>FAPIcidfmap</code>. -Second, you can redirect PostScript fonts to FAPI, setting -entries in <code>FAPIconfig</code> file.</p> - -<p> -Names <code>FAPIfontmap</code>, <code>FAPIcidfmap</code>, <code>FAPIconfig</code> -in this text actually are placeholders, which may be substituted with command line arguments : -<code>-sFAPIfontmap=<em>name1</em></code> <code>-sFAPIcidfmap=<em>name2</em></code> -<code>-sFAPIconfig=<em>name3</em></code>. -Ghostscript searches the specified file names as explained in -<a href="#Finding_files">How Ghostscript finds files</a>. -Default values for these arguments are equal to argument names. -When building Ghostscript with <code>COMPILE_INITS=1</code>, only default values are used.</p> - -<p> -Font files, which are being handled with FAPI, may reside in any directory in your hard disk. -Paths to them to be specified in <code>FAPIfontmap</code> and -with special command line arguments, explained below. -The path may be either absolute or relative. Relative ones are being resolved from the path, -which is specified in <code>FAPIconfig</code> file.</p> -<p> -The file <code>FAPIfontmap</code> is actually special PostScript code. -It may include records of 2 types : general records -and FCO records (see below).</p> - -<p> -A general record describes a font, which is being rendered with FAPI. -They must end with semicolon. Each general record is a pair. -The first element of the pair is the font name (the name that PostScript -documents use to access the font, which may differ -from real name of the font which the font file defines). -The second element is a dictionary with entries :</p> - -<table> - <tr><th>Key</th> - <th>Type</th> - <th>Description</th></tr> -<tr> <td>Path</td> - <td>string</td> - <td>Absolute path to font file, or relative path to font file from the FontPath value, - being specified in <code>FAPIconfig</code>.</td></tr> -<tr> <td>FontType</td> - <td>integer</td> - <td>PostScript type for this font. Only 1 and 42 are currently allowed. - Note that this is unrelated to the real type of the font file - - the bridge will perform a format conversion.</td></tr> -<tr> <td>FAPI</td> - <td>name</td> - <td>Name of the renderer to be used with the font. - Only <code>/UFST</code> and <code>/FreeType</code> are now allowed.</td></tr> -<tr> <td>SubfontId</td> - <td>integer</td> - <td>(optional) Index of the font in font collection, such as FCO or TTC. - It is being ignored if Path doesn't specify a collection. - Note that Free Type can't handle FCO. - Default value is 0.</td></tr> -<tr> <td>Decoding</td> - <td>name</td> - <td>(optional) The name of a Decoding resource to be used with the font. - If specified, <code>lib/xlatmap</code> (see below) doesn't work for this font.</td></tr> -</table> - -<p> -Example of a general FAPI font map record :</p> -<blockquote> -<code> -/FCO1 << /Path (/AFPL/UFST/fontdata/MTFONTS/PCLPS3/MT1/PCLP3__F.fco) /FontType 1 /FAPI /UFST >> ; -</code> -</blockquote> - -<p> -FCO records work for UFST only. -A group of FCO records start with a line <code><em>name</em> ReadFCOfontmap:</code>, -where <code><em>name</em></code> is a name of a command line argument, -which specify a path to an FCO file. The group of FCO records -must end with the line <code>EndFCOfontmap</code>. -Each record of a group occupy a single line, -and contains a number and 1, 2 or 3 names. -The number is the font index in the FCO file, the first name -is the Postscript font name, the secong is an Encoding resource name, -and the third is a decoding resource name.</p> - -<p> -Note that <code>FAPIfontmap</code> specifies only instances of -Font category. CID fonts to be listed in another map file.</p> - -<p> -Ghostscript distribution includes sample map files -<code>gs/lib/FAPIfontmap</code>, -<code>gs/lib/FCOfontmap-PCLPS2</code>, -<code>gs/lib/FCOfontmap-PCLPS3</code>, -<code>gs/lib/FCOfontmap-PS3</code>, -which may be customized by the user. -The last 3 ones include an information about UFST FCO files.</p> - -<p> -The file <code>FAPIcidfmap</code> defines a mapping table for -CIDFont resources. It contains records for each CID font being rendered with FAPI. -The format is similar to <code>FAPIfontmap</code>, - but dictionaries must contain few different entries :</p> - -<table> - <tr><th>Key</th> - <th>Type</th> - <th>Description</th></tr> -<tr> <td>Path</td> - <td>string</td> - <td>Absolute path to font file, or relative path to font file from the CIDFontPath value, - being specified in <code>FAPIconfig</code>.</td></tr> -<tr> <td>CIDFontType</td> - <td>integer</td> - <td>PostScript type for this CID font. Only 0, 1 and 2 are currently allowed. - Note that this is unrelated to the real type of the font file - - the bridge will perform format conversion.</td></tr> -<tr> <td>FAPI</td> - <td>name</td> - <td>Name of the renderer to be used with the font. - Only <code>/UFST</code> and <code>/FreeType</code> are now allowed.</td></tr> -<tr> <td>SubfontId</td> - <td>integer</td> - <td>(optional) Index of the font in font collection, such as FCO or TTC. - It is being ignored if Path doesn't specify a collection. - Default value is 0.</td></tr> -<tr> <td>CSI</td> - <td>array of 2 elements</td> - <td>(required) Information for building <code>CIDSystemInfo</code>. - The first element is a string, which specifies <code>Ordering</code>. - The second element is a number, which specifies <code>Supplement</code>.</td></tr> -</table> - -<p> - Example of FAPI CID font map record :</p> -<blockquote> -<code> -/HeiseiKakuGo-W5 << /Path (/WIN2000/Fonts/PMINGLIU.TTF) /CIDFontType 0 /FAPI /UFST /CSI [(Japan1) 2] >> ; -</code> -</blockquote> - - -<p> -The control file <code>FAPIconfig</code> defines 4 entries :</p> - -<table> - <tr><th>Key</th> - <th>Type</th> - <th>Description</th></tr> -<tr> <td>FontPath</td> - <td>string</td> - <td>Absolute path to a directory, which contains fonts. Used to resolve - relative paths in <code>FAPIfontmap</code>.</td></tr> -<tr> <td>CIDFontPath</td> - <td>string</td> - <td>Absolute path to a directory, which contains fonts to substitute to CID fonts. - Used to resolve relative paths in <code>FAPIcidfmap</code>. - It may be same or different than FontPath.</td></tr> -<tr> <td>HookDiskFonts</td> - <td>array of integers.</td> - <td>List of PS font types to be handled with FAPI. - This controls other fonts that ones listed in <code>FAPIfontmap</code> - and <code>FAPIcidfmap</code> - such ones are PS fonts installed to - Ghostscript with <code>lib/fontmap</code> or with <code>GS_FONTPATH</code>, - or regular CID font resources. Unlisted font types will be - rendered with the native Ghostscript font renderer. - Only allowed values now are 1,9,11,42. Note that 9 and 11 - correspond to CIDFontType 0 and 2.</td></tr> -<tr> <td>HookEmbeddedFonts</td> - <td>array of integers.</td> - <td>List of PS font types to be handled with FAPI. - This controls fonts being embedded into a document - - either fonts or CID font resources. Unlisted font types will be - rendered with the native Ghostscript font renderer. - Only allowed values now are 1,9,11,42. Note that 9 and 11 - correspond to CIDFontType 0 and 2.</td></tr> - -</table> - -<p> -Ghostscript distribution includes sample config files -<code>gs/lib/FAPIconfig</code>, -<code>gs/lib/FAPIconfig-FCO</code>. -which may be customized by the user. -The last ones defines the configuration -for handling resident UFST fonts only.</p> - -<p> -In special cases you may need to customize the file <code>lib/xlatmap</code>. Follow instructions in it.</p> - -<p> -Some UFST font collections need a path for finding an UFST plugin. -If you run UFST with such font collection, -you should run Ghostscript with a special command line argument -<code>-sUFST_PlugIn=<em>path</em></code>, where <code><em>path</em></code> specifies -a disk path to the UFST plugin file, which Monotype Imaging distributes -in <em><code>ufst/fontdata/MTFONTS/PCL45/MT3/plug__xi.fco</code></em>. -If UFST needs it and the -command line argument is not specified, Ghostscript prints a warning and searches -plugin file in the current directory.</p> - -<p> -If you want to run UFST with resident UFST fonts only -(and allow Ghostscript font renderer to handle fons, which may be downloaded or embedded into documents), -you should run Ghostscript with these command line arguments : -<code>-sFCOfontfile=<em>path1</em></code> <code>-sFCOfontfile2=<em>path2</em></code> -<code>-sUFST_PlugIn=<em>path3</em></code> -<code>-sFAPIfontmap=<em>map-name</em></code> <code>-sFAPIconfig=FAPIconfig-FCO</code> -where <code><em>path1</em></code> specifies -a disk path to the main FCO file, <code><em>path2</em></code> specifies -a disk path to the Wingdings FCO file, <code><em>path3</em></code> -a disk path the FCO plugin file, <code><em>path1</em></code> is either -<code>gs/lib/FCOfontmap-PCLPS2</code>, -<code>gs/lib/FCOfontmap-PCLPS3</code>, or -<code>gs/lib/FCOfontmap-PS3</code>. -<code>FAPIcidfmap</code> works as usual, but probably you want to leave it empty -because FCO doesn't emulate CID fonts.</p> - -<p> -Some configurations of UFST need a path for finding symbol set files. -If you compiled UFST with such configuration, -you should run Ghostscript with a special command line argument -<code>-sUFST_SSdir=<em>path</em></code>, where <code><em>path</em></code> specifies -a disk path to the UFST support directory, which Monotype Imagong distributes -in <em><code>ufst/fontdata/SUPPORT</code></em>. If UFST needs it and the -command line argument is not specified, Ghostscript prints a warning and searches -symbol set files in the current directory.</p> - - -<p> -Note that UFST and Free Type cannot handle some Ghostscript fonts because -they do not include a PostScript interpreter and therefore have stronger restrictions on -font formats than Ghostscript itself does - in particular, Type 3 fonts. -If their font types are listed in <code>HookDiskFonts</code> or in -<code>HookEmbeddedFonts</code>, Ghostscript interprets them as PS files, -then serializes font data into a RAM buffer and passes it to FAPI as -PCLEOs. (see the FAPI-related source code for details).</p> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/VectorDevices.htm b/doc/VectorDevices.htm deleted file mode 100644 index c05a7ccf..00000000 --- a/doc/VectorDevices.htm +++ /dev/null @@ -1,1503 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>High Level Output Devices</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>High Level Output Devices</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Overview">Overview</a></li> - <li><a href="#PXL">PCL-XL file output</a></li> - <li><a href="#TXT">Text output</a></li> - <li><a href="#DOCX">DOCX file output</a></li> - <li><a href="#XPS">XPS file output</a></li> - <li><a href="#PDFWRITE">PDF file output</a></li> - <li> - <ul> - <li><a href="#COMMON">Common controls and features</a> - <li><a href="#PSPDF_IN">Controls and features specific to PostScript and PDF input</a> - <li><a href="#PXL_IN">Controls and features specific to PCL and PXL input</a> - <li><a href="#PDF">PDF file output</a> - <li><a href="#PS">PostScript file output</a> - <li><a href="#EPS">EPS file output</a> - </ul> - </li> - <li><a href="#PDFX">PDF/X-3 file output</a></li> - <li><a href="#PDFA">PDF/A file output</a></li> - <li><a href="#PPD">Ghostscript PDF printer description</a></li> - <li><a href="#Extensions">pdfmark extensions</a></li> - <li><a href="#Limitations">Limitations</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript overview</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Overview"></a>Overview</h2> - -<p> -High level devices are Ghostscript output devices which do not render to a raster, -in general they produce 'vector' as opposed to bitmap output. Such devices currently -include: pdfwrite, ps2write, eps2write, txtwrite, xpswrite, pxlmono, pxlcolor and -docxwrite. -</p> - -<p> -Although these devices produce output which is not a raster, they still work in the -same general fashion as all Ghostscript devices. The input (PostScript, PDF, XPS, PCL -or PXL) is handled by an appropriate interpreter, the interpreter processes the input -and produces from it a sequence of drawing 'primitives' which are handed to the device. -The device decides whether to handle the primitive itself, or call upon the graphics -library to render the primitive to the final raster. -</p> - -<p> -Primitives are quite low level graphics operations; as an example consider the PDF -sequence '0 0 100 100 re f'. This constructs a rectangle with the bottom left -corner at 0,0 which is 100 units wide by 100 units high, and fills it with the current -color. A lower level implementation using only primitives would first move the current -point to 0,0, then construct a line to 0,100, then a line to 100,100, a line to 100, 0 -and finally a line back to 0,0. It would then fill the result. -</p> - -<p> -Obviously that's a simple example but it serves to demonstrate the point. -</p> - -<p> -Now the raster devices all call the graphics library to process primitives (though they -may choose to take some action first) and render the result to a bitmap. The high level -devices instead reassemble the primitives back into high level page description and -write the result to a file. This means that the output, while it should be visually the -same as the input (because it makes the same marks), is <b>not</b> the same as the -original input, even if the output Page Description Language is the same as the input -one was (eg PDF to PDF). -</p> - -<p> -Why is this important ? Firstly because the description of the page won't be the same, -if your workflow relies upon (for example) finding rectangles in the description then -it might not work after it has been processed by a high level device, as the -rectangles may all have turned into lengthy path descriptions. -</p> -<p>In addition, any part of the original input which does not actually make marks on the -page (such as hyperlinks, bookmarks, comments etc) will normally <b>not</b> be -present in the output, even if the output is the same format. In general the PDF -interpreter and the PDF output device (pdfwrite) try to preserve the non-marking -information from the input, but some kinds of content are not carried across, in -particular comments are not preserved. -</p> - -<p> -We often hear from users that they are 'splitting' PDF files, or 'modifying' them, or converting -them to PDF/A, and it's important to realize that this is not what's happening. Instead, -a new PDF file is being created, which should <b>look</b> the same as the original, but -the actual insides of the PDF file are not the same as the original. This may not be a -problem, but if it's important to keep the original contents, then you need to use -a different tool (we'd suggest MuPDF, also available from Artifex). Of course, if the -<b>intention</b> is to produce a modified PDF file (for example, reducing the resolution -of images, or changing the colour space), then clearly you cannot keep the original -contents unchanged, and pdfwrite performs these tasks well. -</p> - - -<hr> -<h2><a name="PXL"></a>PCL-XL (PXL)</h2> - -<p>The <tt>pxlmono</tt> and <tt>pxlcolor</tt> devices output HP PCL-XL, -a graphic language understood by many recent laser printers. - -<h3>Options</h3> -<blockquote> -<dl> -<dt><code>-dCompressMode=<em>1 | 2 | 3</em></code> (default is 1) -<dd>Set the compression algorithm used for bitmap graphics. RLE=1, JPEG=2, DeltaRow=3. -When JPEG=2 is on, it is applied only to full-color images; indexed-color graphics -and masks continues to be compressed with RLE. -</dl></blockquote> - -<hr> -<h2><a name="TXT"></a>Text output</h2> - -<p> The txtwrite device will output the text contained in the original -document as Unicode. - -<h3>Options</h3> -<blockquote> -<dl> -<dt><code>-dTextFormat=<em>0 | 1 | 2 | 3 | 4 </em></code> (default is 3)</dt> - <dd>Format 0 is intended for use by developers and outputs XML-escaped Unicode -along with information regarding the format of the text (position, font name, -point size, etc). The XML output is the same format as the MuPDF output, but -no additional processing is performed on the content, so no block detection.<p></dd> -<dd>Format 1 uses the same XML output format, but attempts similar processing to -MuPDF, and will output blocks of text. Note the algorithm used is not the same -as the MuPDF code, and so the results will not be identical.<p></dd> -<dd>Format 2 outputs Unicode (UCS2) text (with a Byte Order Mark) which -approximates the layout of the text in the original document.<p></dd> -<dd>Format 3 is the same as format 2, but the text is encoded in UTF-8.<p></dd> -<dd>Format 4 is internal format similar to Format 0 but with extra information.<p></dd> -</dl></blockquote> - -<p> - -<hr> -<h2><a name="DOCX"></a>DOCX output</h2> - -<p>The docxwrite device creates a DOCX file suitable for use with applications -such as Word or LibreOffice, containing the text in the original document. -</p> -<p>Rotated text is placed into textboxes. Heuristics are used to group -glyphs into words, lines and paragraphs; for some types of formatting, these -heuristics may not be able to recover all of the original document structure. -</p> -<p>This device currently has no special configuration parameters.</p> - -<p> - -<hr> -<h2><a name="XPS"></a>XPS file output</h2> - -<p>The xpswrite device writes its output according to the Microsoft XML Paper Specification. This -specification was later amended to the Open XML Paper specification, submitted to ECMA International -and adopted as ECMA-388. -</p> -<p>This device currently has no special configuration parameters.</p> -</p> -<p> - -<hr> -<h2><a name="PDFWRITE"></a>The family of PDF and PostScript output devices</h2> - -<blockquote><ul> -<li><a href="#COMMON">Common controls and features</a> -<li><a href="#PSPDF_IN">Controls and features specific to PostScript and PDF input</a> -<li><a href="#PXL_IN">Controls and features specific to PCL and PXL input</a> -<li><a href="#PDF">PDF file output</a> -<li><a href="#PS">PostScript file output</a> -<li><a href="#EPS">EPS file output</a> -</ul></blockquote> - -<h3><a name="COMMON"></a>Common controls and features</h3> -<p> -The PDF and PostScript (including Encapsulated PostScript, or EPS) devices have much of their code -in common, and so many of the controlling parameters are also common amongst the devices. -The pdfwrite, ps2write and eps2write devices create PDF or PostScript files whose visual appearance should match, as closely -as possible, the appearance of the original input (PS, PDF, XPS, PCL, PXL). There are a number of caveats -as mentioned in the <a href="#Overview">overview</a> above. In addition to the general comments there are some additional points that -bear mentioning; -</p> -<p> -PCL has a graphics model which differs significantly from the PostScript or PDF one, in particular it has -a form of transparency called RasterOps, some aspects of which cannot be represented in PDF at a high -level (or at all, in PostScript). The pdfwrite device makes no attempt to handle this, and the resulting PDF file will <b>not</b> match -the original input. The only way to deal with these types of file is to render the whole page to a bitmap -and then 'wrap' the bitmap as a PDF file. Currently we do not do this either, but it is possible that a -future enhancement may do so. -</p> -<p> -If the input contains PDF-compatible transparency, but the ps2write device is selected, or the pdfwrite device -is selected, but has been told to limit the PDF feature set to a version less than 1.4, the transparency -cannot be preserved. In this case the entire page is rendered to a bitmap and that bitmap is 'wrapped up' -in appropriate PDF or PostScript content. The output should be visually the same as the input, but since -it has been rendered it will not scale up or down well, unlike the original, vector, content of the input. -</p> - -<p> -The <em>options</em> in the command line may include any switches that may -be used with the language interpreter appropriate for the input (see <a -href="Use.htm#Options">here</a> for a complete list). In addition the -following options are common to all the pdfwrite family of devices, and should -work when specified on the command line with any of the language interpreters. - -<dl> - -<dt><code>-r</code><em>resolution</em> -<dd>Sets the resolution for pattern fills, for fonts that must be -converted to bitmaps and any other rendering required (eg rendering -transparent pages for output to PDF versions < 14). The default internal -resolution for pdfwrite is 720dpi. - -<dt><code>-dUNROLLFORMS</code><dd>When converting from PostScript, -pdfwrite (and ps2write) preserve the use of Form resources as Form -XObjects in the output. Some badly written PostScript can cause this -to produce incorrect output (the Quality Logic CET tests for example). -By setting this flag, forms will be unrolled and stored in the output -each time they are used, which avoids the problems. Note that the output -file will of course be larger this way. -We do not attempt to preserve Form XObjects from PDF files, unless they -are associated with transparency groups. - -<dt><code>-dNoOutputFonts</code></dt><dd>Ordinarily the pdfwrite device family -goes to considerable lengths to preserve fonts from the input as fonts -in the output. However in some highly specific cases it can be useful to -have the text emitted as linework/bitmaps instead. Setting this switch -will prevent these devices from emitting any fonts, all text -will be stored as vectors (or bitmaps in the case of bitmapped fonts) -in the page content stream. Note that this will produce larger output -which will process more slowly, render differently and particularly -at lower resolution produce less consistent text rendering. Use with -caution. - -<dt><code>-dCompressFonts=</code><em>boolean</em> -<dd>Defines whether <code>pdfwrite</code> will compress embedded fonts in -the output. The default value is <code>true</code>; the -<code>false</code> setting is intended only for debugging as it will result in larger output. - -<dt><code>-dCompressStreams=</code><em>boolean</em> -<dd>Defines whether <code>pdfwrite</code> will compress streams other than those in fonts or pages in -the output. The default value is <code>true</code>; the -<code>false</code> setting is intended only for debugging as it will result in larger output. - -</dl> -<h4><a name="distillerparams"></a>Distiller Parameters</h4> -<p> -<em>Options</em> may also include -<code>-d</code><em>parameter</em>=<em>value</em> or -<code>-s</code><em>parameter</em>=<em>string</em> switches for setting -"distiller parameters", Adobe's documented parameters for controlling the -conversion of PostScript into PDF. The PostScript <code>setdistillerparams</code> and -<code>currentdistillerparams</code> operators are also recognized when -the input is PostScript, and provide an equivalent way to set these -parameters from within a PostScript input file. -</p> -<p>Although the name implies that these parameters are for controlling PDF output, in -fact the whole family of devices use these same parameters to control the conversion into -PostScript and EPS as well. -</p> - -<p> -The pdfwrite family of devices recognize all of the Acrobat Distiller 5 parameters -defined in the DistillerParameters (version 5) document available from the Adobe web site. -Cells in the table below containing '=' mean that the value of the parameter is the same as in the -"default" column. - -<blockquote> -<table> -<tr> -<th align="left" style="width:31%">Parameter name</th> - -<th align="left" style="width:11.5%">Notes</th> - -<th align="left" style="width:11.5%">default</th> - -<th align="left" style="width:11.5%">screen</th> - -<th align="left" style="width:11.5%">ebook</th> - -<th align="left" style="width:11.5%">printer</th> - -<th align="left" style="width:11.5%">prepress</th> -</tr> -<tr valign=top><td><code>AlwaysEmbed</code></td><td><a href="#note_13">(13)</a></td><td>[ ]</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AntiAliasColorImages</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AntiAliasGrayImages</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AntiAliasMonoImages</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ASCII85EncodePages</code></td><td></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AutoFilterColorImages</code></td><td><a href="#note_1">(1)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AutoFilterGrayImages</code></td><td><a href="#note_1">(1)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AutoPositionEPSFiles</code></td><td><a href="#note_0">(0)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>AutoRotatePages</code></td><td></td><td>/PageByPage</td><td>/PageByPage</td><td>/All</td><td>/None</td><td>/None</td></tr> -<tr valign=top><td><code>Binding</code></td><td><a href="#note_0">(0)</a></td><td>/Left</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>CalCMYKProfile</code></td><td><a href="#note_0">(0)</a></td><td>()</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>CalGrayProfile</code></td><td><a href="#note_0">(0)</a></td><td>()</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>CalRGBProfile</code></td><td><a href="#note_0">(0)</a></td><td>()</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>CannotEmbedFontPolicy</code></td><td><a href="#note_0">(0)</a></td><td>/Warning</td><td>/Warning</td><td>/Warning</td><td>/Warning</td><td>/Error</td></tr> -<tr valign=top><td><code>ColorACSImageDict</code></td><td><a href="#note_13">(13)</a></td><td><a href="#note_7">(note 7)</a></td><td><a href="#note_10">(note 10)</a></td><td><a href="#note_10">(note 10)</a></td><td><a href="#note_8">(note 8)</a></td><td><a href="#note_9">(note 9)</a></td></tr> -<tr valign=top><td><code>ColorConversionStrategy</code></td><td><a href="#note_6">(6)</a></td><td>LeaveColorUnchanged</td><td>RGB</td><td>RGB</td><td>UseDeviceIndependentColor</td><td>LeaveColorUnchanged</td></tr> -<tr valign=top><td><code>ColorImageDepth</code></td><td></td><td>-1</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ColorImageDict</code></td><td><a href="#note_13">(13)</a></td><td><a href="#note_7">(note 7)</a></td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ColorImageFilter</code></td><td></td><td>/DCTEncode</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ColorImageDownsampleThreshold</code></td><td></td><td>1.5</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ColorImageDownsampleType</code></td><td><a href="#note_3">(3)</a></td><td>/Subsample</td><td>/Average</td><td>/Average</td><td>/Average</td><td>/Bicubic</td></tr> -<tr valign=top><td><code>ColorImageResolution</code></td><td></td><td>72</td><td>72</td><td>150</td><td>300</td><td>300</td></tr> -<tr valign=top><td><code>CompatibilityLevel</code></td><td></td><td>1.7</td><td>1.5</td><td>1.5</td><td>1.7</td><td>1.7</td></tr> -<tr valign=top><td><code>CompressPages</code></td><td><a href="#note_14">(14)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ConvertCMYKImagesToRGB</code></td><td></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ConvertImagesToIndexed</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>CoreDistVersion</code></td><td></td><td>4000</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>CreateJobTicket</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>false</td><td>false</td><td>true</td><td>true</td></tr> -<tr valign=top><td><code>DefaultRenderingIntent</code></td><td></td><td>/Default</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>DetectBlends</code></td><td><a href="#note_0">(0)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>DoThumbnails</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>false</td><td>false</td><td>false</td><td>true</td></tr> -<tr valign=top><td><code>DownsampleColorImages</code></td><td></td><td>false</td><td>true</td><td>true</td><td>false</td><td>false</td></tr> -<tr valign=top><td><code>DownsampleGrayImages</code></td><td></td><td>false</td><td>true</td><td>true</td><td>false</td><td>false</td></tr> -<tr valign=top><td><code>DownsampleMonoImages</code></td><td></td><td>false</td><td>true</td><td>true</td><td>false</td><td>false</td></tr> -<tr valign=top><td><code>EmbedAllFonts</code></td><td></td><td>true</td><td>false</td><td>true</td><td>true</td><td>true</td></tr> -<tr valign=top><td><code>EmitDSCWarnings</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>EncodeColorImages</code></td><td></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>EncodeGrayImages</code></td><td></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>EncodeMonoImages</code></td><td></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>EndPage</code></td><td><a href="#note_0">(0)</a></td><td>-1</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>GrayACSImageDict</code></td><td><a href="#note_13">(13)</a></td><td><a href="#note_7">(note 7)</a></td><td><a href="#note_7">(note 7)</a></td><td><a href="#note_10">(note 10)</a></td><td><a href="#note_8">(note 8)</a></td><td><a href="#note_9">(note 9)</a></td></tr> -<tr valign=top><td><code>GrayImageDepth</code></td><td></td><td>-1</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>GrayImageDict</code></td><td><a href="#note_13">(13)</a></td><td><a href="#note_7">(note 7)</a></td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>GrayImageDownsampleThreshold</code></td><td></td><td>1.5</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>GrayImageDownsampleType</code></td><td><a href="#note_3">(3)</a></td><td>/Subsample</td><td>/Average</td><td>/Bicubic</td><td>/Bicubic</td><td>/Bicubic</td></tr> -<tr valign=top><td><code>GrayImageFilter</code></td><td></td><td>/DCTEncode</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>GrayImageResolution</code></td><td></td><td>72</td><td>72</td><td>150</td><td>300</td><td>300</td></tr> -<tr valign=top><td><code>ImageMemory</code></td><td><a href="#note_0">(0)</a></td><td>524288</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>LockDistillerParams</code></td><td></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>LZWEncodePages</code></td><td><a href="#note_2">(2)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>MaxSubsetPct</code></td><td></td><td>100</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>MonoImageDepth</code></td><td></td><td>-1</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>MonoImageDict</code></td><td><a href="#note_13">(13)</a></td><td><<K -1>></td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>MonoImageDownsampleThreshold</code></td><td></td><td>1.5</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>MonoImageDownsampleType</code></td><td></td><td>/Subsample</td><td>/Subsample</td><td>/Subsample</td><td>/Subsample</td><td>/Subsample</td></tr> -<tr valign=top><td><code>MonoImageFilter</code></td><td></td><td>/CCITTFaxEncode</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>MonoImageResolution</code></td><td></td><td>300</td><td>300</td><td>300</td><td>1200</td><td>1200</td></tr> -<tr valign=top><td><code>NeverEmbed</code></td><td><a href="#note_13">(13)</a></td><td><a href="#note_11">(note 11)</a><a href="#note_12">(note 12)</a></td><td><a href="#note_11">(note 11)</a><a href="#note_12">(note 12)</a></td><td><a href="#note_11">(note 11)</a><a href="#note_12">(note 12)</a></td><td>[ ]<a href="#note_12">(note 12)</a></td><td>[ ]<a href="#note_12">(note 12)</a></td></tr> -<tr valign=top><td><code>OffOptimizations</code></td><td></td><td>0</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>OPM</code></td><td></td><td>1</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>Optimize</code></td><td><a href="#note_0">(0</a>,<a href="#note_5">5)</a></td><td>false</td><td>true</td><td>true</td><td>true</td><td>true</td></tr> -<tr valign=top><td><code>ParseDSCComments</code></td><td></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>ParseDSCCommentsForDocInfo</code></td><td></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>PreserveCopyPage</code></td><td><a href="#note_0">(0)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>PreserveEPSInfo</code></td><td><a href="#note_0">(0)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>PreserveHalftoneInfo</code></td><td></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>PreserveOPIComments</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>false</td><td>false</td><td>true</td><td>true</td></tr> -<tr valign=top><td><code>PreserveOverprintSettings</code></td><td></td><td>false</td><td>false</td><td>false</td><td>true</td><td>true</td></tr> -<tr valign=top><td><code>sRGBProfile</code></td><td><a href="#note_0">(0)</a></td><td>()</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>StartPage</code></td><td><a href="#note_0">(0)</a></td><td>1</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>SubsetFonts</code></td><td></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>TransferFunctionInfo</code></td><td><a href="#note_4">(4)</a></td><td>/Preserve</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>UCRandBGInfo</code></td><td></td><td>/Remove</td><td>/Remove</td><td>/Remove</td><td>/Preserve</td><td>/Preserve</td></tr> -<tr valign=top><td><code>UseFlateCompression</code></td><td><a href="#note_2">(2)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>UsePrologue</code></td><td><a href="#note_0">(0)</a></td><td>false</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>PassThroughJPEGImages</code></td><td><a href="#note_15">(15)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -<tr valign=top><td><code>PassThroughJPXImages</code></td><td><a href="#note_16">(16)</a></td><td>true</td><td>=</td><td>=</td><td>=</td><td>=</td></tr> -</table></blockquote> - -<p> -<a name="note_0">(note 0)</a> -This parameter can be set and queried, but currently has no effect. - -<p> -<a name="note_1">(note 1)</a> -<code>-dAutoFilterxxxImages=false</code> works since Ghostscript version 7.30. -Older versions of Ghostscript don't examine the image to -decide between JPEG and LZW or Flate compression: they always use -Flate compression. - -<p> -<a name="note_2">(note 2)</a> -Because the LZW compression scheme was covered by patents at the time this -device was created, <code>pdfwrite</code> does not actually use LZW compression: -all requests for LZW compression are ignored. -<tt>UseFlateCompression</tt> is treated as always on, but the switch <code>CompressPages</code> -can be set to false to turn off page level stream compression. -Now that the patent has expired, we could change this should it become worthwhile. - -<p> -<a name="note_3">(note 3)</a> -The <code>xxxDownsampleType</code> parameters can also have the value -/Bicubic (a Distiller 4 feature), this will use a Mitchell filter. (older -versions of pdfwrite simply used Average instead). Note; if a non-integer -downsample factor is used the code will clamp to the nearest integer (if -the difference is less than 0.1) or will silently switch to the old bicubic -filter, NOT the Mitchell filter. - -<p> -<a name="note_4">(note 4)</a> -The default for transfer functions is to preserve them, this is because transfer functions are -a device-dependent feature, a set of transfer functions designed for an RGB device will give -incorrect output on a CMYK device for instance. The pdfwrite device does now support /Preserve, -/Apply and /Remove (the previous documentation was incorrect, application of transfer functions -was not supported). PDF 2.0 deprecates the use of transfer functions, and so when producing PDF 2.0 -compatible output if the TransferFunctionInfor is set to /Preserve it will be silently replaced with /Apply. -You can instead specifically set TransferFunctionInfo to /Remove when producing PDF 2.0 in order to -avoid the transfer function being applied. - -<p> - -<a name="note_5">(note 5)</a> -Use the -dFastWebView command line switch to 'optimize' output. -<p> - -<a name="note_6">(note 6)</a> - -The value <code>UseDeviceIndependentColorForImages</code> works the same as -<code>UseDeviceIndependentColor</code>. -The value <code>sRGB</code> actually converts to RGB with the default Ghostscript conversion. -The new Ghostscript-specific value <code>Gray</code> converts all colors to DeviceGray. -With the introduction of new color conversion code in version 9.11 it is no longer necessary to -set <code>ProcessColorModel</code> when selecting <code>Gray</code>, <code>RGB</code> or <code>CMYK</code>. It is also no -longer necessary to set <code>UseCIEColor</code> for <code>UseDeviceIndependentColor</code> to -work properly, and the use of <code>UseCIEColor</code> is now strongly discouraged. -<p> -<a name="note_7">(note 7)</a> - The default image parameter dictionary is -<blockquote><code> -<< /QFactor 0.9 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> -</code></blockquote> - -<p> -<a name="note_8">(note 8)</a> -The printer ACS image parameter dictionary is -<blockquote><code> -<< /QFactor 0.4 /Blend 1 /ColorTransform 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> -</code></blockquote> - -<p> -<a name="note_9">(note 9)</a> -The prepress ACS image parameter dictionary is -<blockquote><code> -<< /QFactor 0.15 /Blend 1 /ColorTransform 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> -</code></blockquote> - -<p> -<a name="note_10">(note 10)</a> -The screen and ebook ACS image parameter dictionary is -<blockquote><code> -<< /QFactor 0.76 /Blend 1 /ColorTransform 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> -</code></blockquote> - -<p> -<a name="note_11">(note 11)</a> -The default, screen, and ebook settings never embed the 14 standard fonts -(Courier, Helvetica, and Times families, Symbol, and ZapfDingbats). -This behaviour is intentional but can be overridden by: -<blockquote><code> -<< /NeverEmbed [ ] >> setdistillerparams -</code></blockquote> - -<p> -<a name="note_12">(note 12)</a> -<code>NeverEmbed</code> can include CID font names. -If a CID font is substituted in <code>lib/cidfmap</code>, -the substitute font name is used when the CID font is embedded, -and the original CID font name is used when it is not embedded. -<code>NeverEmbed</code> should always specify the original CID font -name. - -<p> -<a name="note_13">(note 13)</A> -The arrays <code>AlwaysEmbed</code> and <code>NeverEmbed</code> and -image parameter dictionaries <code>ColorACSImageDict</code>, -<code>ColorACSImageDict</code>, <code>ColorImageDict</code>, - -<code>GrayACSImageDict</code>, <code>GrayImageDict</code>, -<code>MonoImageDict</code> cannot be specified on the command line. -To specify these, you must use PostScript, either by including it in the PostScript source -or by passing the <code>-c</code> command-line parameter to ghostscript as described in <a href="#Limitations">Limitations</A> below. -For example, including the PostScript string in your file <tt>in.ps</tt>: -<blockquote><tt><</AlwaysEmbed [/Helvetica /Times-Roman]>> setdistillerparams</tt></blockquote> -is equivalent to invoking: - -<blockquote><code>gs -dBATCH -dSAFER -DNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=out.pdf -c -'<</AlwaysEmbed [/Helvetica /Times-Roman]>> setdistillerparams' -f -in.ps</code></blockquote> - -or using the extra parameters in a file: - -<blockquote><code>@params.in</code></blockquote> - -where the file <b>params.in</b> contains: - -<blockquote><code>-c '<</AlwaysEmbed [/Helvetica /Times-Roman]>> setdistillerparams' -f -in.ps</code></blockquote> - -<p> -<a name="note_14">(note 14)</a> -The default value of <code>CompressPages</code> is <code>false</code> for ps2write and eps2write. - -<p> -<a name="note_15">(note 15)</a> -When <code>true</code> image data in the source which is encoded using the DCT (JPEG) filter will not be decompressed -and then recompressed on output. This prevents the multiplication of JPEG artefacts caused by lossy compression. -</code><code>PassThroughJPEGImages</code> currently only affects simple JPEG images. It has no effect on JPX (JPEG2000) encoded images (see below) -or masked images. In addition this parameter will be ignored if the pdfwrite device needs to modify the source data. This can happen if the image -is being downsampled, changing colour space or having transfer functions applied. Note that this parameter essentially overrides -the 'EncodeColorImages' and 'EncodeGrayImages' parameters if they are false, the image will still be written with a DCTDecode filter. NB this -feature currently only works with PostScript or PDF input, it does not work with PCL, PXL or XPS input. - -<p> -<a name="note_16">(note 16)</a> -When <code>true</code> image data in the source which is encoded using the JPX (JPEG 2000) filter will not be decompressed -and then recompressed on output. This prevents the multiplication of JPEG artefacts caused by lossy compression. -</code><code>PassThroughJPXImages</code> currently only affects simple JPX encoded images. It has no effect on JPEG encoded images (see above) -or masked images. In addition this parameter will be ignored if the pdfwrite device needs to modify the source data. This can happen if the image -is being downsampled, changing colour space or having transfer functions applied. Note that this parameter essentially overrides -the 'EncodeColorImages' and 'EncodeGrayImages' parameters if they are false, the image will still be written with a JPXDecode filter. NB this -feature currently only works with PostScript or PDF input, it does not work with PCL, PXL or XPS input. - -<h4><a name="Color_Conversion_and_Management"></a>Color Conversion and Management</h4> -<p> -As of the 9.11 pre-release, the color management in the pdfwrite family has been substantially -altered so that it now uses the same Color Management System as rendering (the default -is LCMS2). This considerably improves the color handling in both pdfwrite and ps2write, -particularly in the areas of Separation and DeviceN color spaces, and Indexed color -spaces with images. -</p> - -<p>Note that while pdfwrite uses the same CMS as the rendering devices, this does not mean that the entire suite of options is available, as described -in the GS9_Colour Management.pdf file. The colour management code has no effect at all unless either ColorConversionStrategy -or ConvertCMYKImagesToRGB is set, or content has to be rendered to an image (this is rare and usually required only when -converting a PDF file with transparency to a version < PDF 1.4). -</p> -<p>Options based on object type (image, text, linework) are not used, all objects are converted using the same scheme. -<code>-dKPreserve</code> has no effect because we will not convert CMYK to CMYK. <code>-dDeviceGrayToK</code> also has no effect; -when converting to CMYK DeviceGray objects are left in DeviceGray since that can be mapped directly to the K channel.</p> - -The <code>ColorConversionStrategy</code> switch can now be set to <code>LeaveColorUnchanged</code>, <code>Gray</code>, <code>RGB</code>, <code>CMYK</code> or -<code>UseDeviceIndependentColor</code>. Note that, particularly for ps2write, <code>LeaveColorUnchanged</code> may still need to convert -colors into a different space (ICCbased colors cannot be represented in PostScript for example). <code>ColorConversionStrategy</code> can be specified either as; a string -by using the <code>-s</code> switch (<code>-sColorConversionStrategy=RGB</code>) or as a name using the <code>-d</code> switch (<code>-dColorConversionStrategy=/RGB</code>). -</p> -<p>ps2write cannot currently convert into device-independent color spaces, and so <code>UseDeviceIndependentColor</code>should not be used with ps2write (oe eps2write). -</p> -<p>All other color spaces are converted appropriately. Separation and DeviceN spaces will be preserved if possible (ps2write cannot preserve DeviceN or Lab) -and if the alternate space is not appropriate a new alternate space will be created. Eg a [/Separation (MyColor) /DeviceRGB {...}] -when the <code>ColorConversionStrategy</code> is set to <code>CMYK</code> would be converted to [/Separation (MyColor) /DeviceCMYK {...}] -The new tint transform will be created by sampling the original tint transform, converting the RGB values into CMYK, and then creating -a function to linearly interpolate between those values.</p> - -The <code>PreserveSeparation</code> switch now controls whether the pdfwrite family of devices will attempt to preserve Separation spaces. If this is set to false then -all Separation colours will be converted into the current device space specified by ProcessColorModel. -</p> - -<h4><a name="Orientation"></a>Setting page orientation</h4> - -<p> -By default Ghostscript determines viewing page orientation based on the dominant -text orientation on the page. Sometimes, when the page has text in several -orientations or has no text at all, wrong orientation can be selected. - -<p> -Acrobat Distiller parameter <code>AutoRotatePages</code> controls the -automatic orientation selection algorithm. On Ghostscript, besides -input stream, Distiller parameters can be given as command line arguments. -For instance: <code>-dAutoRotatePages=/None</code> or -<code>/All</code> or <code>/PageByPage</code>. - -<p> -When there is no text on the page or automatic page rotation is set to -<code>/None</code> an orientation value from setpagedevice is used. -Valid values are: <code>0</code> (portrait), -<code>3</code> (landscape), <code>2</code> (upside down), -and <code>1</code> (seascape). The orientation can be set from the -command line as <code>-c "<</Orientation 3>> setpagedevice"</code> -using Ghostscript directly but cannot be set in <code>ps2pdf</code>. -See <a href="#Limitations">Limitations</a> below. - -<p> -Ghostscript passes the orientation values from DSC comments to the -<code>pdfwrite</code> driver, and these are compared with the -auto-rotate heuristic. If they are different then the DSC value will be used preferentially. -If the heuristic is to be preferred over the DSC comments then comment parsing -can be disabled by setting <code>-dParseDSCComments=false</code>. -<p> - -<h3><a name="PSPDF_IN"></a>Controls and features specific to PostScript and PDF input</h3> -<dl><dt><code>-dPDFSETTINGS=</code><em>configuration</em></dt> -<dd>Presets the "distiller parameters" to one of four predefined settings:</dd> -</dl> -<ul> - -<li><code>/screen</code> selects low-resolution output similar to the -Acrobat Distiller (up to version X) "Screen Optimized" setting.</li> - -<li><code>/ebook</code> selects medium-resolution output similar to the -Acrobat Distiller (up to version X) "eBook" setting.</li> - -<li><code>/printer</code> selects output similar to the Acrobat Distiller -"Print Optimized" (up to version X) setting.</li> - -<li><code>/prepress</code> selects output similar to Acrobat Distiller -"Prepress Optimized" (up to version X) setting.</li> - -<li><code>/default</code> selects output intended to be useful across a -wide variety of uses, possibly at the expense of a larger output file.</li> - -</ul> -<p> -NB Adobe has recently changed the names of the presets it uses in Adobe Acrobat Distiller, -in order to avoid confusion with earlier versions we do not plan to change the -names of the PDFSETTINGS parameters. The precise value for each control is listed -in the table <a href="#distillerparams">above</a>. -</p> - -<dl><dt></dt> -<dd>Please be aware that the <code>/prepress</code> setting does <b>not</b> indicate -the highest quality conversion. Using any of these presets will involve altering the -input, and as such may result in a PDF of poorer quality (compared to the input) than -simply using the defaults. The 'best' quality (where best means closest to the original -input) is obtained by not setting this parameter at all (or by using <code>/default</code>). -</dd> - -<dd>The PDFSETTINGS presets should only be used if you are sure you understand that the -output will be altered in a variety of ways from the input. It is usually better to -adjust the controls individually (see the table below) if you have a genuine requirement to produce, -for example, a PDF file where the images are reduced in resolution. -</dd> -</dl> - -<h3><a name="PXL_IN"></a>Controls and features specific to PCL and PXL input</h3> -<p> -Many of the controls used for <a href="#distillerparams">distiller parameters</a> can be used on the command line with the -d or -s -switches, and these will work correctly with PCL or PXL input. However, some controls (eg /NeverEmbed) do -not take simple numeric or string arguments, and these cannot be set from the command line. When -the input is PostScript or PDF we can use the -c and -f switches to send PostScript through -the interpreter to control these parameters, but clearly this is not possible when the interpreter -does not understand PostScript. In addition some features are controlled using the PostScript -<code>pdfmark</code> operator and again that clearly is not possible unless we are using a PostScript -interpreter to read the input. -</p> -<p> -To overcome this new, GhostPCL-specific, PJL parameters have been added. These parameters are defined -as <code>PDFMARK</code> and <code>SETDISTILLERPARAMS</code>. In order to reduce confusion when using -PostScript and PCL as inputs these PJL parameters take essentially the same PostScript constructs as -the corresponding PostScript operators <code>pdfmark</code> and <code>setdistillerparams</code>. However -it is important to realise that these are <b>not</b> processed by a full PostScript interpreter, and -there are syntactic rules which must be followed carefully when using these parameters. -</p> -<p> -You cannot use arbitrary PostScript operators, only boolean, number, name, string, array and dictionary -objects are supported (but see <code>PUTFILE</code> later). All tokens <b>must</b> be separated by white space, so -while this <code>[/Test(string)]</code> is perfectly valid in PostScript, you must instead write it -as <code>[ /Test (string) ]</code> for PJL parsing. All <code>PDFMARK</code> and <code>SETDISTILLERPARAMS</code> must be set as -DEFAULT, the values must be on a single line, and delimited by "". -</p> -<p> -pdfmarks sometimes require the insertion of file objects (especially for production of PDF/A files) so -we must find some way to handle these. This is done (for the pdfmark case only) by defining a special -(non-standard) pdfmark name <code>PUTFILE</code>, this simply takes the preceding string, and uses -it as a fully qualified path to a file. Any further pdfmark operations can then use the named object -holding the file to access it. -</p> -<p> -The easiest way to use these parameters is to create a 'settings' file, put all the commands in it, -and then put it on the command line immediately before the real input file. For example: -</p> -<code> -./gpcl6 -sDEVICE=pdfwrite -dPDFA=1 -dCompressPages=false -dCompressFonts=false -sOutputFile=./out.pdf ./pdfa.pjl ./input.pcl -</code></p> -<p> -Where pdfa.pjl contains the PJL commands to create a PDF/A-1b file (see example below).</p> -<p> -<h4>Example creation of a PDF/A output file</h4> -<p>For readability the line has been bisected, when used for real this must be a single line. The 'ESC' represents -a single byte, value 0x1B, an escape character in ASCII. The line must end with an ASCII newline (\n, 0x0A) and this must be the only newline following the @PJL. -The line breaks between "" below should be replaced with space characters, the double quote charcters (") are required.</p> -<code> -</p> -<pre> -ESC%-12345X -@PJL DEFAULT PDFMARK = " -[ /_objdef {icc_PDFA} /type /stream /OBJ pdfmark -[ {icc_PDFA} << /N 3 >> /PUT pdfmark -[ {icc_PDFA} (/ghostpdl/iccprofiles/default_rgb.icc) /PUTFILE pdfmark -[ /_objdef {OutputIntent_PDFA} /type /dict /OBJ pdfmark -[ {OutputIntent_PDFA} << /S /GTS_PDFA1 /Type /OutputIntent /DestOutputProfile {icc_PDFA} /OutputConditionIdentifier (sRGB) >> /PUT pdfmark -[ {Catalog} << /OutputIntents [{OutputIntent_PDFA}] >> /PUT pdfmark -[ /Author (Ken) /Creator (also Ken) /Title (PDF/A-1b) /DOCINFO pdfmark -" -</pre> -</code> -<h4>Example using DISTILLERPARAMS to set the quality of JPEG compression.</h4> -<p> -<code> -ESC%-12345X -@PJL DEFAULT SETDISTILLERPARAMS = "<< /ColorImageDict << /QFactor 0.7 /Blend 1 /HSamples [ 2 1 1 2 ] /VSamples [ 2 1 1 2 ] >> >>" -</code> -</p> - -<h3><a name="PDF"></a>PDF file output</h3> -<dl> -<dt><code>-dMaxInlineImageSize=</code><em>integer</em> -<dd>Specifies the maximum size of an inline image, in bytes. For images larger -than this size, <code>pdfwrite</code> will create an XObject instead of embedding -the image into the context stream. -The default value is <code>4000</code>. -Note that redundant inline images must be embedded each time they occur in the -document, while multiple references can be made to a single XObject image. Therefore -it may be advantageous to set a small or zero value if the source document is expected -to contain multiple identical images, reducing the size of the generated PDF.<p></dd> - -<dt><code>-dDoNumCopies</code> -<dd>When present, causes pdfwrite to use the #copies or /NumCopies entry in the page -device dictionary to duplicate each page in the output PDF file as many times as -the 'copies' value. This is intended for use by workflow applications like CUPS -and should not be used for generating general purpose PDF files. In particular any -pdfmark operations which rely on page numbers, such as Link or Outline annotations -will not work correctly with this flag.<p></dd> - -<dt><code>-dDetectDuplicateImages</code> -<dd> Takes a Boolean argument, when set to true (the default) pdfwrite will compare all new - images with all the images encountered to date (NOT small images which are stored in-line) to see if the new image - is a duplicate of an earlier one. If it is a duplicate then instead of writing a new image into the PDF file, - the PDF will reuse the reference to the earlier image. - This can considerably reduce the size of the output PDF file, but increases the - time taken to process the file. - This time grows exponentially as more images are added, and on large input files with - numerous images can be prohibitively slow. Setting this to false will improve performance at the cost of final file size.<p></dd> - -<dt><code>-dFastWebView</code> -<dd> Takes a Boolean argument, default is false. When set to true pdfwrite will -reorder the output PDF file to conform to the Adobe 'linearised' PDF specification. -The Acrobat user interface refers to this as 'Optimised for Fast Web Viewing'. -Note that this will cause the conversion to PDF to be slightly slower and will -usually result in a slightly larger PDF file.</dd> -<dd>This option is incompatible with producing an encrypted (password protected) PDF file.<p></dd> -</dt> -</dl> - -<dl> - <dt><code>-dPreserveAnnots=</code><em>boolean</em> - <dd>We now attempt to preserve most annotations from input PDF files as annotations in the output PDF file (note, not in output PostScript!) - There are a few annotation types which are not preserved, most notably Link and Widget annotations. However, should you wish to revert - to the old behaviour, or find that the new behaviour leads to problems, you can set this switch to false which will cause all annotations to be - inserted into the page content stream, instead of preserved as annotations. - <p> In addition, finer control is available by defining an array - <code>/PreserveAnnotTypes</code>. Annotation types listed in this array will - be preserved, whilst those not listed will be drawn according to the setting os ShowAnnots and ShowAnnotTypes. - By using the controls PreserveAnnots, PreserveAnnotTypes, ShowAnnots and ShowAnnotTypes it is possible to select - by annotation type whether annotations are preserved as annotations, drawn into the page, or simply dropped. - </p> - <p> To use this feature: - <code>-c "/PreserveAnnotTypes [....] def" -f <input file></code> - <br> Where the array can contain one or more of the following names: - <code>/Stamp</code>, <code>/Squiggly</code>, <code>/Underline</code>, <code>/Link</code>, <code>/Text</code>, <code>/Highlight</code>, <code>/Ink</code>, <code>/FreeText</code>, <code>/StrikeOut</code> and <code>/stamp_dict</code>.</p> - <p> For example, adding the follow to the command line: - <code>-c "/PreserveAnnotTypes [/Text /UnderLine] def" -f <input file></code> - <br> would preserve only annotations with the subtypes "Text" and "UnderLine"</p> - </dd> - </dt> -</dl> - -<dl> - <dt><code>-dPreserveMarkedContent=</code><em>boolean</em></dt> - <dd>We now attempt to preserve marked content from input PDF files through to the output PDF file (note, not in output PostScript!) - This does not include marked content relating to optional content, because currently we do not preserve optional content, it is - instead applied by the interpreter. - <p> - This control also requires the PDF interpreter to pass the marked content to the pdfwrite device, this is only done with the - new (C-based) PDF interpreter. THe old (PostScript-based) interpreter does not support this feature and will not pass marked - content to the pdfwrite device. - </p> - </dd> -</dl> - -The following options are useful for creating PDF 1.2 files: -<p> - -<dl> - - <dt><code>-dPatternImagemask=<em>boolean</em></code></dt> - <dd>With <code>CompatibilityLevel < 1.3 </code> it specifies whether - the target viewer handles <code>ImageMask</code> with a pattern color. - Some old viewers, such as Ghostscript 3.30 fail with such constructs. - Setting this option to false, one can get more compatibility, - but the mask interpolation is lost. - With <code>CompatibilityLevel ≥ 1.3 </code> this option is ignored. - Default value is <code>false</code>.<p></dd> - - <dt><code>-dMaxClipPathSize=<em>integer</em></code></dt> - <dd>Specifies the maximum number of elements in the clipping path - that the target viewer can handle. This option is used only with - <code>CompatibilityLevel < 1.3</code> and - <code>PatternImagemask=false</code>, - and only when converting a mask into a clipping path. - If the clipping path exceeds the specified size, - the masked image and the clipping path is decomposed into smaller images. - The value of the option counts straight path segments - (curved segments are not used for representing a mask). - Default value is <code>12000</code>.<p></dd> - - <dt><code>-dMaxShadingBitmapSize=<em>integer</em></code></dt> - <dd>Specifies the maximum number of bytes allowed for representing a shading as a bitmap. - If a shading exceeds this value, the resolution of the output bitmap - is reduced to fit into the specified number of bytes. - Note that the number of bytes depends on the number of color components - in <code>ProcessColorModel</code> or <code>ColorConversionStrategy</code>, assumes 8 bits per sample, - and doesn't consider image compression or downsampling. The image is rendered at the current resolution - as specified by <code>-r</code> or the default of 720 dpi. - - Default value is <code>256000</code>. - In general larger values will result in higher quality, - but the output file size may increase dramatically, particularly with shadings which cover large areas. - - Shadings should generally only be rendered to images if <code>CompatibilityLevel</code> is 1.2 or less - or if <code>ColorCoversionStrategy</code> specifies a color space different to that of the shading.<p></dd> - - <dt><code>-dHaveTrueTypes=<em>boolean</em></code></dt> - <dd>With <code>CompatibilityLevel < 1.3</code> it specifies - whether the target viewer can handle TrueType fonts. - If not, TrueType fonts are converted into raster fonts - with resolution specified in <code>HWResolution</code>. Note that large text at higher resolutions - results in very large bitmaps which are likely to defeat caching in many printers. As a result the - text is emitted as simple images rather than as a (type 3) bitmap font. The PostScript user parameter - MaxFontItem can be used to increase the maximum size of a cache entry which will increase the size/resolution - of the text which can be stored in a font. - With <code>CompatibilityLevel ≥ 1.3</code> this option is ignored. Default value is <code>true</code>. - </dd> -</dl> - -<p> -The following options are useful for creating PDF 1.3 files: -<p> - -<dl> - - <dt><code>-dHaveTransparency=<em>boolean</em></code></dt> - <dd>With <code>CompatibilityLevel ≥ 1.4</code> it specifies - whether the target viewer can handle PDF 1.4 transparency objects. - If not, the page is converted into a single plain image with all - transparency flattened. - Default value is <code>true</code>.</dd> - -</dl> - -<h4>The following option specifies creation of a PDF/X-3 file</h4> - -<dl> -<dt><code>-dPDFX=</code><em>boolean</em> -<dd>Specifies the generated document is to follow the PDF/X-3 standard. -When true, a <code>DefaultRGB</code> <code>ColorSpace</code> resource -must be defined, and options <code>NOSUBSTDEVICECOLORS</code>, -<code>NOCIE</code> must not be specified. -Default value is <code>false</code>. -<p>The pdfwrite device does not currently support PDF/X versions other than 3.</p> -</dl> - -<p> - -When generating a PDF/X-3 document, Ghostscript performs the following -special actions to satisfy the PDF/X-3 standard: -<ul> - <li> All fonts are embedded.</li> - <li> <code>DeviceRGB</code> color space is substituted with - <code>the DefaultRGB</code> color space, - which must be defined in the <code>ColorSpace</code> category. - The easiest way is to provide it in the <code>DefaultRGB</code> file in the resource directory.</li> - <li> <code>DeviceRGB</code> color values are passed unchanged. - If a user needs a non trivial color adjustment, a non trivial - <code>DefaultRGB</code> color space must be defined.</li> - <li> Transfer functions and halftone phases are skipped.</li> - <li> <code>/PS pdfmark</code> interprets the <code>DataSource</code> - stream or file.</li> - <li><code>TrimBox</code> and <code>BleedBox</code> entries - are generated in page descriptions. - Their values can be changed using the - <code>PDFXTrimBoxToMediaBoxOffset</code>, - <code>PDFXSetBleedBoxToMediaBox</code>, and - <code>PDFXBleedBoxToTrimBoxOffset</code> - distiller parameters (see below).</li> -</ul> - - -<h4><a name="Encryption"></a> -The following switches are used for creating encrypted documents : -</h4> - -<dl> -<dt><code>-sOwnerPassword=</code><em>string</em></dt> -<dd>Defines that the document be encrypted with the specified -owner password.</dd> -</dl> - -<dl> -<dt><code>-sUserPassword=</code><em>string</em></dt> -<dd>Defines the user password for opening the document. -If empty, the document can be opened with no password, -but the owner password is required to edit it.</dd> -</dl> - -<dl> -<dt><code>-dPermissions=</code><em>number</em></dt> -<dd>Defines the PDF permissions flag field. Negative values are allowed -to represent unsigned integers with the highest bit set. See the PDF -Reference manual for the meaning of the flag bits.</dd> -</dl> - -<dl> -<dt><code>-dEncryptionR=</code><em>number</em></dt> -<dd>Defines the encryption method revision number - either 2 or 3.</dd> -</dl> - -<dl> -<dt><code>-dKeyLength=</code><em>number</em></dt> -<dd>Defines the length (in bits) of the encryption key. -Must be a multiple of 8 in the interval [40, 128]. -If the length isn't 40, <code>-dEncryptionR</code> must be 3.</dd> -</dl> - - -<h4><a name="Metadata"></a> -The following switches are used for generating metadata according to the Adobe XMP specification : -</h4> - -<dl> -<dt><code>-sDocumentUUID=</code><em>string</em></dt> -<dd>Defines a DocumentID to be included into the document Metadata. -If not specified, Ghostscript generates an UUID automatically. -Otherwise the specified string is copied into the document without -checking its syntax or consistence. -<p> -Note that Adobe XMP specification requires DocumentID must be same -for all versions of a document. Since Ghostscript does not provide -a maintenance of document versions, users are responsible to provide -a correct UUID through this parameter. -<p> -Note that Ghostscript has no assess to the host node ID -due to a minimization of platform dependent modules. -Therefore it uses an MD5 hash of the document contents for generating UUIDs.</p> -</dl> - -<dl> -<dt><code>-sInstanceUUID=</code><em>string</em> -<dd>Defines a instance ID to be included into the document Metadata. -If not specified, Ghostscript generates an UUID automatically. -Otherwise the specified string is copied into the document without -checking its syntax or consistence. -<p> -Note that the Adobe XMP specification requires the instance ID to be unique -for all versions of the document. This parameter may be used to disable -unique ID generation for debug purposes. - -<p> -When none of <code>DocumentUUID</code> -and <code>InstanceUUID</code> are specified, -the generated DocumentID appears same as instance ID. -</dl> - -<dl> -<dt><code>-sDocumentTimeSeq=</code><em>integer</em> -<dd>Defines an integer to be used as a deconflictor for generating -UUIDs, when several invocations of Ghostscript create -several PDF documents within same clock quantum (tick). -Mainly reserved for very fast computers and/or multithreading applications, -which may appear in future. If both <code>DocumentUUID</code> -and <code>InstanceUUID</code> are specified, <code>DocumentTimeSeq</code> is ignored. -</dl> - -<dl> -<dt><code>-sDSCEncoding=</code><em>string</em> -<dd>Defines the name of a Postscript encoding in which -DSC comments in the source document are encoded. -If specified, the comments are converted -from that encoding into Unicode UTF-8 when writing <code>Metadata</code>. -If not specified, the comments are copied to <code>Metadata</code> -with no conversion. Note that Adobe Distiller for -Windows uses the default locale's code page -for this translation, so it's result may differ from Ghostscript. -Adobe Acrobat appears to use <code>PDFDocEncoding</code> when -displaying document's properties, -so we recommend this value. -</dl> - -<dl> - -<dt><a name="UseOCR"></a><code>-sUseOCR=</code><em>string</em> -<dd>Controls the use of OCR in pdfwrite. If enabled this will use an OCR -engine to analyse the glyph bitmaps used to draw text in a PDF file, and -the resulting Unicode code points are then used to construct a ToUnicode -CMap. -<p> -PDF files containing ToUnicode CMaps can be searched, use copy/paste and -extract the text, subject to the accuracy of the ToUnicode CMap. Since not all -PDF files contain these it can be beneficial to create them. -</p> -<p> -Note that, for English text, it is possible that the existing standard character -encoding (which most PDF consumers will fall back to in the absence of Unicode -information) is better than using OCR, as OCR is not a 100% reliable process. -OCR processing is also comparatively slow. -</p> -<p> -For the reasons above it is useful to be able to exercise some control over the -action of pdfwrite when OCR processing is available, and the <code>UseOCR</code> -parameter provides that control. There are three possible values: -</p> -<ul> -<li><code>Never</code> Default - don't use OCR at all even if support is built-in.</li> -<li><code>AsNeeded</code> If there is no existing ToUnicode information, use OCR.</li> -<li><code>Always</code> Ignore any existing information and always use OCR.</li> -</ul> -<p> -Our experimentation with the Tesseract OCR engine has shown that the more text we -can supply for the engine to look at, the better the result we get. We are, unfortunately, -limited to the graphics library operations for text as follows. -</p> -<p> -The code works on text 'fragments'; these are the text sequences sent to the text -operators of the source language. Generally most input languages will try to send -text in its simplest form, eg "Hello", but the requirements of justification, kerning -and so on mean that sometimes each character is positioned independently on the page. -</p> -<p> -So pdfwrite renders all the bitmaps for every charcter in the text document, when -set up to use OCR. Later, if any character in the font does not have a Unicode -value already we use the bitmaps to assemble a 'strip' of text which we then send -to the OCR engine. If the engine returns a different number of recognised characters -than we expected then we ignore that result. We've found that (for English text) -constructions such as ". The" tend to ignore the full stop, presumably because the OCR -engine thinks that it is simply noise. In contrast "text." does identify the full -stop correctly. So by ignoring the failed result we can potentially get a better result -later in the document. -</p> -<p> -Obviously this is all heuristic and undoubtedly there is more we can do to improve the -functionality here, but we need concrete examples to work from. -</p> -</dd> -</dt> -</dl> - -<h3><a name="PS"></a>PostScript file output</h3> -<p> -The <code>ps2write</code> device handles the same set of distiller -parameters as -are handled by the <code>pdfwrite</code> device (and 2 unique extensions, see below). -<p> -The option <code>-dMaxInlineImageSize=</code><em>integer</em> -must not be used with <code>ps2write</code> as all images are inline in PostScript. -</p> - -<a name="AdditionalDistillerParams"></a> -<p> -There are also two additional (not Adobe-standard) Distiller parameters, specific to ps2write: -<dl> -<dt> -<code>/PSDocOptions</code><em> string</em> -<dd>No default value. If defined, the contents of the string will be emitted in the output PostScript prolog -enclosed within %%BeginSetup and %%EndSetup comments. This is intended as a means of introducing device-specific document wide -setup or configuration options into the output. Default media selection, printer resolution etc might be included here. - -<code>/PSPageOptions</code><em> array of strings</em> -</dd> -<dd>No default value. If defined, the contents of the strings in the array will be emitted in the output PostScript at the start -of each page, one string per page, enclosed within %%BeginPageSetup and %%EndPageSetup comments. This is intended as a means of introducing device-specific -setup or configuration options into the output on a page by page basis. The strings are used from the array sequentially, if there are more -pages than strings then we 'wrap round' and start again with the first string. This makes it convenient to do setup for even/odd pages -by simply including 2 strings in the array. - -<p> -Note: executing setpagedevice will reset distiller parameters to the default, if you use any of these options via setdistillerparams, and - expect to execute setpagedevice, you should set /LockDistillerParams true. Ordinarily the PDF interpreter executes setpagedevice for - every page in order to set the media size. -</p> -</dd> -</dt> -</dl> - -<p> -NB the strings contained in PSDocOptions, and the PSPageOptions array, are written verbatim to the output. No error checking is (or can be) performed on these strings -and it is the users responsibility to ensure they contain well formed PostScript which does not cause errors on the target device. -</p> -</p> -<p> -There are also the following ps2write specific options : -<p> - -<dl> -<dt> -<code>-dProduceDSC=</code><em>boolean</em> -<dd> Default value is true. When this value is true the output PostScript file will be constructed in a way which is compatible with the Adobe Document Structuring Convention, and will include a set of comments appropriate for use by document managers. This enables features such as page extraction, N-up printing and so on to be performed. When set to false, the output file will not be DSC-compliant. Older versions of Ghostscript cannot produce DSC-compliant output from ps2write, and the behaviour for these older versions matches the case when <code>ProduceDSC</code> is false. -</dl> - -<dl> -<dt> -<code>-dCompressEntireFile=</code><em>boolean</em> -<dd>When this parameter is true, the <code>LZWEncode</code> -and <code>ASCII85Encode</code> filters will be applied to the entire output file. -In this case <code>CompressPages</code> should be false to prevent a dual compression. -When this parameter is false, these filters will be applied to the initial procset only, -if <code>CompressPages</code> is true. -Default value is <code>false</code>. -</dl> -<p> -Note: It is not possible to set <code>CompressEntireFile</code> when <code>ProduceDSC</code> is true as a single compressed object cannot conform to the DSC. It is possible to set <code>CompressPages</code> which will also compress the ps2write ProcSet. -</p> -<h4><a name="printer_control"></a>Controlling device-specific behavior</h4> - -<p> -A few options can be used to influence the behavior of a printer or -PostScript interpreter that reads the result of ps2ps2. All of these options -are incompatible with DSC-compliant PostScript, in order to use any of them -<code>ProduceDSC</code> must be set to false. - -<dl> -<dt><code>-dRotatePages=</code><em>boolean</em>. -<dd>The printer will rotate pages -for a better fit with the physical size. Default value : <em>false</em>. -Must be <em>false</em> if <code>-dSetPageSize=true</code>. - -<dt><code>-dFitPages=</code><em>boolean</em>. -<dd>The printer will scale pages down -to better fit the physical page size. The rendering quality may be poor due to the scaling, -especially for fonts which Ghostscript had converted into bitmaps -(see the <em>ps2write</em> device parameter <code>HaveTrueTypes</code>; -See <a href="#Options">Options</a> about the <code>PageSize</code> entry of the <code>Policies</code> -dictionary while the conversion step). -Default value : <em>false</em>. -Must be <em>false</em> if <code>-dSetPageSize=true</code> or <code>-dCenterPages=true</code>. - -<dt><code>-dCenterPages=</code><em>boolean</em>. -<dd>The printer will center the page image on the selected media. Compatible with <code>-dRotatePages=true</code>, which may rotate the image on the media if it fits better, and then center it. -Default value : <em>false</em>. -Must be <em>false</em> if <code>-dSetPageSize=true</code> or <code>-dFitPages=true</code>. - -<dt><code>-dSetPageSize=</code><em>boolean</em>. -<dd>The printer will try to set page size from the job. -Only use with printers which can handle random <em>PageSize</em>. -Defaults to <em>true</em>, must be <em>false</em> if <code>-dRotatePages=true</code>, <code>-dCenterPages=true</code> or <code>-dFitPages=true</code>. - -<dt><code>-dDoNumCopies=</code><em>boolean</em>. -<dd>The PostScript emitted by ps2write will try to use copypage to create the number of copies originally requested. Note that this relies on the level 2 semantics for copypage -and will not reliably work on language level 3 devices (such as Ghostscript itself). -Defaults to false. This flag is not compatible with the ProduceDSC flag which will take precedence if set. - -</dl> - -<p> -These correspond to keys in the Postscript <em>userdict</em> -of the target printer's virtual memory to control its behavior while -executing a job generated with <code>ps2write</code>. - -<p> -These keys can be set when executing using the ps2write device, -this 'fixes' the resulting behaviour according to which key has been set. -If these keys are not defined during conversion, the resulting PostScript -will not attempt any form of media selection. - -In this case the behaviour can then be modified by setting the keys, either by modifying the resulting -PostScript or setting the values in some other manner on the target device. - -<p> -See also the distiller params PSDocOptions and PSPageOptions mentioned <a href="#AdditionalDistillerParams">above.</a></p> - -<h3><a name="EPS"></a>Encapsulated PostScript (EPS) file output</h3> - -<p> -The eps2write device is the same as the ps2write device, except that it produces Encapsulated PostScript, which is intended -to be imported into another document and treated as a 'black box'. There are certain restrictions which EPS -files must follow, the primary one being that they must be DSC conformant. This means that you must not set <code>-dProduceDSC</code> -to false. -<p>In addition EPS files may only contain a single page and may not contain device-specific PostScript. You should therefore not -use the <code>PSDocOptions</code> or <code>PSPageOptions</code> or any of the switches noted in the ps2write section -above under <a href="#printer_control">Controlling device specific behaviour</a> -</p> -<hr> -<h2><a name="PDFX"></a>Creating a PDF/X-3 document</h2> - -<p> - -To create a PDF/X-3 document from a Postscript or a PDF file, you should : - -<ul> -<li> Specify the <code>pdfwrite</code> device or use the <code>ps2pdf</code> script. -<li> Specify the <code>-dPDFX</code> option. It provides the document conformity - and forces <code>-dCompatibilityLevel=1.3</code>. -<li> Specify <code>-sColorConversionStrategy=Gray</code>, <code>-sColorConversionStrategy=CMYK</code> - or <code>-sColorConversionStrategy=UseDeviceIndependentColor</code>(<code>RGB</code> is not allowed). - If you plan to create a device-independent color PDF file then you should set the ProcessColorModel - using <code>-sProcessColorModel=DeviceGray</code> or <code>-sProcessColorModel=DeviceCMYK</code>. -<li> Specify a PDF/X definition file before running the input document. - It provides additional information to be included into the output document. - A sample PDF/X definition file may be found in <code>gs/lib/PDFX_def.ps</code>. - You will need to modify the content of this file; in particular you must alter the - /ICCProfile so that it points to a valid ICC profile for your OutputCondition. The - string '(...)' defining the ICCProfile must be a fully qualified device and path - specification appropriate for your Operating System. -<li> If a registered printing condition is applicable, specify its identifier - in the PDF/X definition file. Otherwise provide an ICC profile and - specify it in the PDF/X definition file as explained below. -<li> Provide a <code>DefaultRGB</code> resource file in the ColorSpace resource category. - Either define it in the PDF/X definition file, or provide - a definition of <code>gs/Resource/ColorSpace/DefaultRGB</code> . - <code>gs/Resource/ColorSpace/DefaultRGB</code> is usually - distributed with Ghostscript, its content may not necessarily satisfy your needs, see below. -</ul> - -<p> -NOTE: Unless <code>-dNOSAFER</code> is specified (NOT reccomended!) -the ICC profile will be read using the <code>SAFER</code> file permissions; you must ensure that the profile is -in a directory which is readable according to the <code>SAFER</code> permissions, or that the file itself -is specifically made readable. See Use.htm for details of how to set file permissions for <code>SAFER</code>. -</p> - -<p> -As mentioned above, the PDF/X definition file provides special information, -which the PDF/X-3 standard requires. You can find a sample file in -<code>gs/lib/PDFX_def.ps</code>, and edit it according to your needs. -The file follows Postscript syntax and uses the operator <code>pdfmark</code> -to pass the special information. To ease customisation -the lines likely to need editing in the sample file are marked with the comment <code>% Customize</code>. -They are explained below. - -<dl> -<dt><code>OutputCondition</code> <em>string</em> -<dd>Defines an <code>OutputCondition</code> value for the output intent dictionary. -</dl> - - -<dl> -<dt><code>OutputConditionIdentifier</code> <em>string</em> -<dd>Defines an <code>OutputConditionIdentifier</code> value for the output intent dictionary. -</dl> - -<dl> -<dt><code>ICCProfile</code> <em>string</em> -<dd> May be omitted if <code>OutputConditionIdentifier</code> -specifies a registered identifier of characterized printing condition -(see http://www.color.org/IPA_2003-11_PDFX.pdf). -Defines a file name of an ICC profile file to be included into the output document. -You may specify either an absolute file name, or a relative -path from the working directory. -</dl> - -<dl> -<dt><code>Title</code> <em>string</em> -<dd>Defines the document title. Only useful if the source Postscript file doesn't -define a title with DSC comments. Otherwise remove entire line from definition file. -</dl> - -<dl> -<dt><code>Info</code> <em>string</em> -<dd>Defines an <code>Info</code> value for the output intent dictionary. -</dl> - -<p>The Ghostscript distribution does not contain an ICC profile to be used -for creating a PDF/X-3 document. Users should either create an appropriate one themselves, -or use one from a public domain, or create one with the PDF/X-3 inspector freeware. - -<p>The PDF/X-3 standard requires a <code>TrimBox</code> entry -to be written for all page descriptions. -This is an array of four offsets -that specify how the page is to be trimmed -after it has been printed. -It is set to the same as <code>MediaBox</code> by default -unless the <code>PDFXTrimBoxToMediaBoxOffset</code> -distiller parameter is present. -It accepts offsets to the <code>MediaBox</code> as an array -[<i>left right top bottom</i>], -e.g., the PostScript input code -<code><< /PDFXTrimBoxToMediaBoxOffset -[10 20 30 40] >> setdistillerparams</code> -specifies that 10 points will be trimmed at the left, -20 points at the right, -30 points at the top, -and 40 points at the bottom. - -<p>Another page entry is the <code>BleedBox</code>. -It gives the area of the page -to which actual output items may extend; -cut marks, color bars etc. -must be positioned in the area between the <code>BleedBox</code> -and the <code>MediaBox</code>. -The <code>TrimBox</code> is always contained within the -<code>BleedBox</code>. -By default, -the <code>PDFXSetBleedBoxToMediaBox</code> distiller parameter -is <code>true</code>, -and the <code>BleedBox</code> is set to the same values -as the <code>MediaBox</code>. -If it is set to <code>false</code>, -the <code>PDFXBleedBoxToTrimBoxOffset</code> -parameter gives offset to the <code>TrimBox</code>. -It accepts a four-value array in the same format as the -<code>PDFXTrimBoxToMediaBoxOffset</code> parameter. - -<p> - -Here is a sample command line to invoke Ghostscript for generating a PDF/X-3 document : -<blockquote><code> -gs -dPDFX -dBATCH -dNOPAUSE -sColorConversionStrategy=CMYK -sDEVICE=pdfwrite -sOutputFile=out-x3.pdf PDFX_def.ps input.ps -</code></blockquote> - -<p> -Please also see the <code>PDFACompatibilityPolicy</code> control described under "Creating a PDF/A document" below. The same control is now used to specify the desired behaviour when an input file cannot be converted 'as is' into a PDF/X file. -<p> - -<hr> -<h2><a name="PDFA"></a>Creating a PDF/A document</h2> - -<p> -To create a PDF/A document, please follow the instructions for <a href="#PDFX">creating a PDF/X-3 document</a>, -with the following exceptions : - -<ul> -<li> Specify the <code>pdfwrite</code> device or use the <code>ps2pdf</code> script. -<li> Specify the <code>-dPDFA</code> option to specify PDF/A-1, <code>-dPDFA=2</code> for PDF/A-2 or <code>-dPDFA=3</code> for PDF/A-3 -<li> Specify <code>-sColorConversionStrategy=RGB</code>, <code>-sColorConversionStrategy=CMYK</code> - or <code>-sColorConversionStrategy=UseDeviceIndependentColor</code>. - If you plan to create a device-independent color PDF file then you should set the ProcessColorModel - using <code>-sProcessColorModel=DeviceRGB</code> or <code>-sProcessColorModel=DeviceCMYK</code>. -<li> Specify a PDF/A definition file before running the input document. - It provides additional information to be included in the output document. - A sample PDF/A definition file may be found in <code>gs/lib/PDFA_def.ps</code>. - You will need to modify the content of this file; in particular you must alter the - /ICCProfile so that it points to a valid ICC profile for your OutputIntent. The - string '(...)' defining the ICCProfile must be a fully qualified device and path - specification appropriate for your Operating System. -</ul> - -There is one additional control for PDF/A output: - -<dl> -<dt><code>PDFACompatibilityPolicy</code> <em>integer</em> -<dd>When an operation (eg pdfmark) is encountered which cannot be emitted in a PDF/A compliant file, this policy is consulted, there are currently three possible values: - -<blockquote>0 - (default) Include the feature or operation in the output file, the file will not be PDF/A compliant. Because the document Catalog is emitted before this is encountered, the file will still contain PDF/A metadata but will not be compliant. A warning will be emitted in this case. -</blockquote> -<dd> -<blockquote>1 - The feature or operation is ignored, the resulting PDF file will be PDF/A compliant. A warning will be emitted for every elided feature. -</blockquote> -<dd> -<blockquote>2 - Processing of the file is aborted with an error, the exact error may vary -depending on the nature of the PDF/A incompatibility. -</blockquote> -</dl> - -Here is a sample command line to invoke Ghostscript for generating a PDF/A document : -<blockquote><code> -gs -dPDFA=1 -dBATCH -dNOPAUSE -sColorConversionStrategy=RGB -sDEVICE=pdfwrite -sOutputFile=out-a.pdf PDFA_def.ps input.ps -</code></blockquote> - -<p> - -<hr> -<h2><a name="PPD"></a>Ghostscript PDF Printer Description</h2> -<p> -To assist with creating a PostScript file suitable for conversion -to PDF, ghostscript includes <a href="../lib/ghostpdf.ppd">ghostpdf.ppd</a>, -a PostScript Printer Description (PPD) file. -This allows some <a href="#Options">distiller parameters</a> -to be set when a PostScript file is generated. - -<h3>Windows XP or 2000</h3> -<p> -To install a "Ghostscript PDF" printer on Windows XP, -select the Windows Control Panel, -Printers and Faxes, -Add a Printer, -Local Printer, -Use port FILE: (Print to File), -Have Disk..., -select the directory containing -<a href="../lib/ghostpdf.ppd">ghostpdf.ppd</a> -and -<a href="../lib/ghostpdf.inf">ghostpdf.inf</a>, -select "Ghostscript PDF", -Replace existing driver (if asked), -and answer the remaining questions appropriately. -After installing, open the "Ghostscript PDF" properties, -select the Device Settings tab, -set "Minimum Font Size to Download as Outline" to 0 pixels. -<p> -To set distiller parameters, select the "Ghostscript PDF" -Printing Preferences, then the Advanced button. -The PDF settings are under "Printer Features". - - -<hr> -<h2><a name="Extensions"></a>pdfmark extensions</h2> -<p> -In order to better support the ZugFERD electronic invoice standard (http://www.ferd-net.de/front_content.php?idcat=231&changelang=4) -and potentially other standards in the future, a new non-standard pdfmark has been defined for use by pdfwrite. -</p> -<p> -This pdfmark allows additional Metadata to be defined which will be inserted into the Metadata generated by -the pdfwrite device. This is necessary because the standard requires a PDF/A-3 file be produced, with an extension -schema (and some additional XML data) contained within the Metadata referenced from the Catalog object. -</p> -<p> -While it would be possible to use the existing Metadata pdfmark to write a completely new set of metadata -into the Catalog, creating a conformant set of XML, with all the information synchronised with the /Info -dictionary would be challenging, this pdfmark allows the pdfwrite device to generate all the normal information -leaving the user with only the task of specifying the additional data. - -<code>[ /XML (string containing additional XMP data) /Ext_Metadata pdfmark</code> -</p> - -<hr> -<h2><a name="Limitations"></a>Limitations</h2> - -<p> -<code>The pdfwrite family</code> will sometimes convert input constructs to -lower-level ones, even if a higher-level construct is available. For -example, if the PostScript file uses <code>charpath</code> to set a -clipping path consisting of text, <code>pdfwrite</code> may write the -clipping path as a path in the PDF file, rather than as text, even though -PDF is able to express clipping with text. This is only a performance -issue, and will be improved incrementally over time. - -<p> -Some applications, such as HIGZ, produce PostScript files that use -ridiculously large coordinates. On such files, <code>pdfwrite</code> may -cause a <code>limitcheck</code> error. If this occurs, try reducing the -default internal resolution of 720 dpi by using the <code>-r</code> -switch, e.g., <code>-r300 somefile.ps</code>. - -<p> -<code>pdfwrite</code> ignores the PDF 1.3 (Acrobat 4.x) pdfmarks related to -document content structure: <code>StRoleMap</code>, -<code>StClassMap</code>, <code>StPNE</code>, -<code>StBookmarkRoot</code>, <code>StPush</code>, -<code>StPop</code>, <code>StPopAll</code>, <code>StBMC</code>, -<code>StBDC</code>, <code>EMC</code>, <code>StOBJ</code>, -<code>StAttr</code>, <code>StStore</code>, <code>StRetrieve</code>, -<code>NamespacePush</code>, <code>NamespacePop</code>, and -<code>NI</code>. While this causes some structural information to be -omitted from the output file, the displayed and printed output are normally -not affected. - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/WhatIsGS.htm b/doc/WhatIsGS.htm deleted file mode 100644 index 512e6542..00000000 --- a/doc/WhatIsGS.htm +++ /dev/null @@ -1,161 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript: What Is Ghostscript?</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>What Is Ghostscript?</h1> - -<h4> -There are various products in the Ghostscript family; this document describes what they are, and how they are related.</h4> - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Ghostscript">Ghostscript</a></li> - <li><a href="#GhostPDF">GhostPDF</a></li> - <li><a href="#GhostPDL">GhostPDL</a></li> - <li><a href="#GhostPCL">GhostPCL</a></li> - <li><a href="#GhostXPS">GhostXPS</a></li> - <li><a href="#URWFonts">URW Font Information</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Ghostscript"></a>Ghostscript</h2> - -<p>Ghostscript is an interpreter for PostScript<a href="#foot1">®</a> and Portable Document Format (PDF) files.</p> - -<p>Ghostscript consists of a PostScript interpreter layer, and a graphics library. The graphics library is shared with all the other products in the Ghostscript family, so all of these technologies are sometimes referred to as Ghostscript, rather than the more correct GhostPDL.</p> - -<p>Binaries for Ghostscript and (seel below) GhostPDF (included in the Ghostscript binaries) for various systems can be downloaded from <a href="http://www.ghostscript.com/download">here</a>. -The source can be found in both the Ghostscript and GhostPDL downloads from -the same site.</p> -<hr> - -<h2><a name="GhostPDF"></a>GhostPDF</h2> - -<p>Prior to release 9.55.0 GhostPDF was an interpreter for the PDF page description language -built on top of Ghostscript, and written in the PostScript programming language. From 9.55.0 -onwards there is a new GhostPDF executable, separate from Ghostscript and written in C -rather than PostScript.</p> - -<p>This new interpreter has also been integrated into Ghostscript itself, in order to -preserve the PDF functionality of that interpreter. For now, the old PostScript-based -interpreter remains the default, but the new interpreter is built-in alongside it.</p> - -<p>The intention is that the new interpreter will replace the old one, which will be withdrawn.</p> - -<p>It is possible to control which interpreter is used with the NEWPDF command-line switch. When -this is false (the current default) the old PostScript-based interpreter is used, when NEWPDF -is true then the new C-based interpreter is used.</p> - -<h2><a name="GhostPDL"></a>GhostPDL</h2> - -<p>Historically, we’ve used GhostPDL as an umbrella term to encompass our entire line of products. We've now brought all these disparate products together into a single package, called, appropriately enough, GhostPDL.</p> - -<p>When running on a printer (or server) GhostPDL now automatically detects the type of data being fed to it and processes it accordingly. The individual interpreters all plug into a top-level module that handles both automatic language detection and Printer Job Language (PJL) based configuration.</p> - -<p>The exact set of interpreters present in an installation can be tuned by the integrator for their specific product/use cases.</p> - -<p>In addition to our existing PDL modules (PS, PDF, PCL, PXL, and XPS) we have now added new modules to handle a range of common image formats. With these installed, GhostPDL will handle JPEGs (both JFIF and EXIF), PWGs, TIFFs, PNGs, JBIG2s, and JPEG2000s.</p> - -<p>GhostPDL is available both under the <a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero GPL license</a> -and for <a href="http://www.artifex.com/page/licesnsing-information.html">commercial licensing</a> -from <a href="http://www.artifex.com">Artifex</a>. - -<p>The source code for GhostPDL can be found on -<a href="http://www.ghostscript.com/download">here</a>. -<hr> - -<h2><a name="GhostPCL"></a>GhostPCL</h2> - -<p>GhostPCL is an interpreter for PCL<a href="#foot2">™</a> and PXL files. This consists of an -PCL/PXL interpreter hooked up to the Ghostscript graphics library.</p> - -<p>GhostPCL is available both under the <a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero GPL license</a> and for <a href="http://www.artifex.com/page/licesnsing-information.html">commercial licensing</a> from <a href="http://www.artifex.com">Artifex</a>.</p> - - -<p>Binaries for GhostPCL for various systems can be downloaded from <a href="http://www.ghostscript.com/download">here</a>. The source can be found in the GhostPCL/GhostPDL downloads from the same site.</p> - -<hr> -<h2><a name="GhostXPS"></a>GhostXPS</h2> - -<p>GhostXPS is an interpreter for XPS (XML Paper Specfication) files. This -consists of an XPS interpreter hooked up to the Ghostscript graphics library.</p> - -<p>GhostXPS is available both under the <a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero GPL license</a> -and for <a href="http://www.artifex.com/page/licesnsing-information.html">commercial licensing</a> -from <a href="http://www.artifex.com">Artifex</a>.</p> - -<p>Binaries for GhostXPS for various systems can be downloaded from -<a href="http://www.ghostscript.com/download">here</a>. The -source can be found in the GhostXPS/GhostPDL downloads from the same site.</p> -<hr> - -<h2><a name="URWFonts"></a>URW Font Information</h2> - -<p> The set of truetype fonts in the urwfonts directory are necessary for the PCL/XL interpreter to function properly but they ARE NOT FREE SOFTWARE and are NOT distributed under the GNU GPL/AGPL. They can instead be redistributed under the <a href="https://ghostscript.com/Aladdin_Free_Public_License.html">AFPL license</a> which bars commercial use.</p> - -<p> If your copy of GhostPDL includes these fonts, you should have received a copy of the the Aladdin Free Pubilc License, usually in a file called COPYING.AFPL. If not, please contact Artifex Software, Inc. 1305 Grant Avenue - Suite 200, Novato, CA 94945 USA, or visit http://www.artifex.com/</p> -<hr> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<p><a name="foot1">PostScript</a> is a registered trademark of Adobe Systems Inc.</p> -<p><a name="foot2">PCL</a> is a registered trademark of Hewlett-Packard Company.</p> - -<br/><br/> -<p> -<small>Copyright © 2000-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/default.css b/doc/default.css deleted file mode 100644 index b45a9d19..00000000 --- a/doc/default.css +++ /dev/null @@ -1,362 +0,0 @@ -* { - -webkit-tap-highlight-color: rgba(0,0,0,0); - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, tt, var, -b, u, i, center, - ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - - -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} - -html, body { - position: relative; - height: 100%; -} - -body { - -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ - -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ - -webkit-user-select: text; /* prevent copy paste, to allow, change 'none' to 'text' */ - color:black; - background:#ffffff; - font-family:"Source Sans Pro", sans-serif; /* 200 = ExtraLight, 300 = Light, 400 = regular, 600 = semi-bold, 700 = bold, 900 = black */ - font-weight:400; - font-size:16px; - margin:0px; - padding:0px; - display: grid; -} - -header { - width: 100%; - height:50px; - background: #0075cf url(language-bindings/images/ghostscript.png) 10px center no-repeat; - background-size: 30px 30px; - color: #fff; - line-height: 50px; - text-indent: 50px; - z-index: 1; - display: flex; - justify-content: space-between; - grid-row: 1; -} - -header .title { - display: flex; - justify-content: start; - flex-direction: column; -} - -header h1 { - line-height: 40px; -} - -header h2::after { - content:"Version 9.56.0"; -} - -header h2 { - font-weight: bold; - margin-top:-45px; - font-size: 12px; - color: #fff; - margin-right:10px; -} - -header .search { - width: 50px; - height:50px; - background: #0075cf url(images/icon-search.png) center center no-repeat; - background-size: 50px 50px; -} - -main { - grid-row: 2; - overflow-y: scroll; -} - -main .outer { - max-width: 1280px; - margin: 0px auto 100px; -} - -main .inner { - padding: 20px; -} - -a { - text-decoration: none; - color: #0075cf; -} - -i { - font-style: italic; -} - -p { - line-height: 24px; - margin-bottom: 20px; -} - -hr { - width: 100%; - margin: 50px auto; -} - -/* Number the h2/h3 -- doesn't work on v4/5 browsers */ -h2 { - counter-increment: h2-count; - counter-reset: h3-count; -} - -h2 a:after { - font-size:30px; - content: counter(h2-count) ""; -} - -h3 { - counter-increment: h3-count; -} - -h3 a:after { - font-size:22px; - content: counter(h2-count) "." counter(h3-count) ""; -} - -h2 a:after, h3 a:after { - background-color: black; - padding: 0px 10px; - margin-right: 5px; - border-radius: 5px; - color: white; -} - -header h1 { - font-size:24px; - font-weight:600; - color: #fff; - text-decoration: none; -} - -header a h1 { - color: #fff; -} - -h1 { - font-size:40px; - font-weight:600; - margin-bottom: 20px; -} - -h2 { - font-weight:600; - font-size:26px; - margin-bottom: 20px; -} - -h3 { - font-weight:600; - font-size:20px; - margin-bottom: 10px; -} - -h4 { - font-weight:600; - font-size:16px; - margin-bottom: 10px; -} - -code { - border-radius: 3px; - padding: 2px 6px; - font-family: monospace; -} - -pre { - font-family: monospace; -} - -pre>code { - padding:0; - margin:0; - font-size:100%; - word-break:normal; - white-space:pre; - background:transparent; - border:0; -} - -pre code, pre tt { - display:inline; - padding:0; - margin:0; - overflow:visible; - line-height:inherit; - word-wrap:normal; - background-color:transparent; - border:0 -} - -pre code::before, -pre code::after, -pre tt::before, -pre tt::after { - content:normal -} - -ul { - margin: 0 0 0 20px; -} - -li { - margin: 10px; -} - -table { - margin: 20px 0; - border-collapse: collapse; - table-layout:fixed; - width: 100%; - border: 1px solid #c0c0c0; -} - -th { - font-weight: bold; - background-color:#666; - color: #fff; - border-bottom: 1px solid #c0c0c0; - border-right: 1px solid #c0c0c0; -} - -tr { - text-overflow:clip; -} - -th, td { - text-align: left; - padding:14px; - word-wrap:break-word; -} - -td { - border-right: 1px solid #c0c0c0; -} - -em { - font-style: italic; -} - -ul.toc { - list-style-type:none; -} - -ul.toc li ul { - list-style-type:none; - margin-left: 20px; -} - -blockquote { - background-color:transparent; - width: 100%; - height: auto; - padding: 20px; - border-radius: 10px; - margin: 0 0 20px 0; - border: 1px solid #666; -} - -blockquote strong { - font-size: 16px; - font-weight: bold; -} - -table { - color: #000; -} - -table code { - color: #000; -} - -table tr { - background-color: #fff; - border-bottom: 1px solid #c0c0c0; -} - -table tr:nth-child(2n) { - background-color: #ddd; -} - -/* Dark mode */ -@media (prefers-color-scheme: dark) { - - body { - background-color: #000; - color: white; - } - - a { - text-decoration: none; - color: #289df6; - } - - h2 a:after, h3 a:after { - background-color: white; - color: black; - } - - blockquote { - border: 1px solid #efefef; - } - - table { - color: #fff; - } - - table code { - color: #fff; - } - - table tr { - background-color: #000; - } - - table tr:nth-child(2n) { - background-color: #222; - } - -} - -/* < phone portrait */ -@media all and (max-width : 399px) { - - header h1 { - font-size:18px; - } - -} diff --git a/doc/gdevds32.c b/doc/gdevds32.c deleted file mode 100644 index a59ea7a6..00000000 --- a/doc/gdevds32.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, - CA 94945, U.S.A., +1(415)492-9861, for further information. -*/ - -/* ds32 device:32-bit CMYK TIFF device (downscaled output - * from 32-bit CMYK internal rendering) - * Supports downscaler options similar to the tiffscaled32 device such - * as DownScaleFactor, PostRenderProfile, TrapX, TrapY,and TrapOrder. - * - * No file is written (except for a debug mode that writes a PAM32 file) - * so that raster lines can be passed in memory to a user function. - */ - -#include "stdint_.h" -#include "gdevprn.h" -#include "gxiodev.h" -#include "stdio_.h" -#include "ctype_.h" -#include "gxgetbit.h" -#include "gsicc_cache.h" -#include "gscms.h" -#include "gxdownscale.h" -#include "gp.h" - -/******************************************************************************** - The following section can be added to the end of device/devs.mak - -### -------- Example 32-bit CMYK downscaled device --------------------- ### -# NB: downscale_ is standard in the lib (LIB1s) -$(DD)ds32.dev : $(DEVOBJ)gdevds32.$(OBJ) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS) - $(SETPDEV2) $(DD)ds32 $(DEVOBJ)gdevds32.$(OBJ) - $(ADDMOD) $(DD)ds32 -include $(GLD)page - -$(DEVOBJ)gdevds32.$(OBJ) : $(DEVSRC)gdevds32.c $(gsicc_cache_h) $(gxdownscale_h) $(AK) \ - $(arch_h) $(gdevprn_h) $(stdio__h) $(stdint__h) $(DEVS_MAK) $(MAKEDIRS) - $(DEVCC) $(DEVO_)gdevds32.$(OBJ) $(C_) $(DEVSRC)gdevds32.c - -***************** END OF devs.mak INSERTION *************************************/ - -/* - Once that is added, then rebuild Ghostscript, for example, on linux: - - make DEVICE_DEVS_EXTRA=obj/ds32.dev - - or, on Windows: - - nmake -f psi/msvc32.mak DEVICE_DEVS_EXTRA=obj\ds32.dev - -*/ - -/* ------ The device descriptors ------ */ - -/* Default X and Y resolution */ -#define X_DPI 72 -#define Y_DPI 72 - -/* ------ The ds32 device ------ */ - -static dev_proc_print_page(ds32_print_page); -static dev_proc_get_params(ds32_get_params_downscale_cmyk); -static dev_proc_put_params(ds32_put_params_downscale_cmyk); - -static const gx_device_procs ds32_procs = { - gdev_prn_open, NULL, NULL, gdev_prn_bg_output_page, gdev_prn_close, - NULL, cmyk_8bit_map_color_rgb, - NULL, NULL, NULL, NULL, NULL, NULL, - ds32_get_params_downscale_cmyk, - ds32_put_params_downscale_cmyk, - cmyk_8bit_map_cmyk_color, - NULL, NULL, NULL, gx_page_device_get_page_device -}; - -typedef struct gx_device_ds32_s { - gx_device_common; - gx_prn_device_common; - gx_downscaler_params downscale; - gsicc_link_t *icclink; -} gx_device_ds32; - -const gx_device_ds32 gs_ds32_device = { - prn_device_body(gx_device_ds32, - ds32_procs, - "ds32", - DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, - 600, 600, /* 600 dpi by default */ - 0, 0, 0, 0, /* Margins */ - 4, /* num components */ - 32, /* bits per sample */ - 255, 255, 256, 256, - ds32_print_page), - GX_DOWNSCALER_PARAMS_DEFAULTS, - 0 /* icclink for PostRenderProfile */ -}; - -static int -ds32_get_params_downscale_cmyk(gx_device * dev, gs_param_list * plist) -{ - gx_device_ds32 *const dsdev = (gx_device_ds32 *)dev; - int code = gdev_prn_get_params(dev, plist); - int ecode = code; - - code = gx_downscaler_write_params(plist, &dsdev->downscale, - GX_DOWNSCALER_PARAMS_MFS | - GX_DOWNSCALER_PARAMS_TRAP); - if (code < 0) { - ecode = code; - } - return ecode; -} - -static int -ds32_put_params_downscale_cmyk(gx_device * dev, gs_param_list * plist) -{ - gx_device_ds32 *const dsdev = (gx_device_ds32 *)dev; - int code, ecode; - - code = gx_downscaler_read_params(plist, &dsdev->downscale, - (GX_DOWNSCALER_PARAMS_MFS | - GX_DOWNSCALER_PARAMS_TRAP)); - if (code < 0) - { - ecode = code; - } - if (ecode < 0) - return ecode; - code = gdev_prn_put_params(dev, plist); - return code; -} - -/* below is copied (renamed) from tiff_chunky_post_cm */ -static int ds32_chunky_post_cm(void *arg, byte **dst, byte **src, int w, int h, - int raster) -{ - gsicc_bufferdesc_t input_buffer_desc, output_buffer_desc; - gsicc_link_t *icclink = (gsicc_link_t*)arg; - - /* - void gsicc_init_buffer(gsicc_bufferdesc_t *buffer_desc, unsigned char num_chan, - unsigned char bytes_per_chan, bool has_alpha, bool alpha_first, - bool is_planar, int plane_stride, int row_stride, int num_rows, - int pixels_per_row); - */ - gsicc_init_buffer(&input_buffer_desc, icclink->num_input, 1, false, - false, false, 0, raster, h, w); - gsicc_init_buffer(&output_buffer_desc, icclink->num_output, 1, false, - false, false, 0, raster, h, w); - icclink->procs.map_buffer(NULL, icclink, &input_buffer_desc, &output_buffer_desc, - src[0], dst[0]); - return 0; -} - -#define WRITE_PAM32 /* for debugging */ - -#ifdef WRITE_PAM32 /* debugging code to write a PAM 32 file. */ -static int -debug_write_pam_32(gx_device_ds32 *dsdev, byte *data, int row, FILE *file) -{ - int code = 0; - - if (row == 0) { - /* PAM "magic" ID == 7 */ - code = fprintf(file, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE CMYK\n" - "# Image generated by GPL Ghostscript GIT PRERELEASE\nENDHDR\n", - dsdev->width, dsdev->height); - if (code < 0) - code = gs_error_ioerror; - } - if (code < 0 || fwrite(data, 1, 4*dsdev->width, file) != 4*dsdev->width) - code = gs_error_ioerror; - - return code; -} -#endif - -static int -ds32_print_page(gx_device_printer * pdev, FILE * file) -{ - gx_device_ds32 *const dsdev = (gx_device_ds32 *)pdev; - int code = 0; - byte *data = NULL; - int size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); - int row; - int factor = dsdev->downscale.downscale_factor; - int height = pdev->height / factor; - int bpc = 8; - int num_comps = 4; - int trap_w = dsdev->downscale.trap_w; - int trap_h = dsdev->downscale.trap_h; - int *trap_order = dsdev->downscale.trap_order; - gx_downscaler_t ds; - - if (dsdev->icclink == NULL) { - code = gx_downscaler_init(&ds, (gx_device *)pdev, - 8, bpc, num_comps, - &dsdev->downscale, - &fax_adjusted_width, 0 /*aw*/); - } else { - code = gx_downscaler_init_cm(&ds, (gx_device *)pdev, - 8, bpc, num_comps, - &dsdev->downscale, - &fax_adjusted_width, 0, /*aw*/ - ds32_chunky_post_cm, dsdev->icclink, - dsdev->icclink->num_output); - } - if (code < 0) - return code; - - data = gs_alloc_bytes(pdev->memory, size, "ds32_print_page(data)"); - if (data == NULL) { - gx_downscaler_fin(&ds); - return_error(gs_error_VMerror); - } - - for (row = 0; row < height && code >= 0; row++) { - code = gx_downscaler_getbits(&ds, data, row); - if (code < 0) - break; -#ifdef WRITE_PAM32 /* debugging code to write a PAM 32 file. */ - if ((code = debug_write_pam_32(dsdev, data, row, file)) < 0) - break; -#endif - /*************************************************************/ - /* User code to handle the row of data (dsdev->width bytes) */ - /* Set code to a negative value (e.g. gs_error_ioerror) if a */ - /* problem occurs. */ - /* Note that nothing needs to be written to 'file' and this */ - /* can be set to '-' (stdout) to avoid leaving an empty file */ - /* if (row == 0) can be used to perform any initialization */ - /* needed to process the user data */ - /*************************************************************/ - - if (code < 0) - break; - } - - /**************************************************************/ - /* User code to finish writing and perform any cleanup needed */ - /**************************************************************/ - - gx_downscaler_fin(&ds); - gs_free_object(pdev->memory, data, "tiff_print_page(data)"); - - return code; -} diff --git a/doc/gs-style.css b/doc/gs-style.css deleted file mode 100644 index 02169581..00000000 --- a/doc/gs-style.css +++ /dev/null @@ -1,56 +0,0 @@ -@charset "UTF-8"; -/* CSS Document */ - -/* Number the h2/h3 -- doesn't work on v4/5 browsers */ -h2 -{ - counter-increment: h2-count; - counter-reset: h3-count; -} - -h2:before -{ - content: counter(h2-count) " "; -} - -h3 -{ - counter-increment: h3-count; -} - -h3:before -{ - content: counter(h2-count) "." counter(h3-count) " "; - -} - -/* table formatting hints */ - -table { - border-collapse: collapse; - border: 1px solid #F2F2F2; - width: 100%; -} - -th, td { - padding: 8px; -} - -tr:nth-child(even){background-color: #f2f2f2} - -th { - background-color: #506B80; - color: white; - font-size: 17px; - border-bottom: 1px solid #F2F2F2; -} - -.table-alt { - border-collapse: collapse; - border: none; - width: 100%; -} - -th, td { - padding: 8px; -}
\ No newline at end of file diff --git a/doc/gs-vms.hlp b/doc/gs-vms.hlp deleted file mode 100644 index 20e45d78..00000000 --- a/doc/gs-vms.hlp +++ /dev/null @@ -1,286 +0,0 @@ -1 gs - gs - GPL Ghostscript interpreter/previewer -! Ghostscript version 9.56.1, 4 April 2022 - Usage: - $ gs [options] [file ...] - - Ghostscript is an implementation of Adobe Systems' PostScript (tm) - and Portable Document Format (PDF) languages. Gs reads files in sequence - and executes them as Ghostscript programs. After doing this, it reads - further input from the standard input stream (normally the keyboard). - Each line is interpreted separately. To exit from the interpreter, - enter the `quit' command. The interpreter also exits gracefully if it - encounters end-of-file. Typing the interrupt character (e.g. Control-C) - is also safe. - -2 Description - The interpreter recognizes several switches described below, which - may appear anywhere in the command line and apply to all files - thereafter. - - You can get a help message by invoking Ghostscript with the -h - or -? option. This message also lists the available devices. - - Ghostscript may be built with multiple output devices. Ghostscript - normally opens the first one and directs output to it. To use - device xyz as the initial output device, include the switch - "-sDEVICE=xyz" - in the command line. Note that this switch must precede the first - .ps file, and only its first invocation has any effect. For example, - for printer output in a normal configuration that includes an Epson - printer driver, you might use the command - gs "-sDEVICE=epson" myfile.ps - instead of just - gs myfile.ps - Alternatively, you can type - (epson) selectdevice - (myfile.ps) run - All output then goes to the printer instead of the display until - further notice. You can switch devices at any time by using the - selectdevice procedure, e.g., - (vga) selectdevice - or - (epson) selectdevice - As yet a third alternative, you can define a logical name GS_DEVICE - as the desired default device name. The order of precedence for these - alternatives, highest to lowest, is: - selectdevice - (command line) - GS_DEVICE - (first device in build list) - - To select the density on a printer, use - gs "-sDEVICE=<device>" -r<xres>x<yres> - For example, on a 9-pin Epson-compatible printer, you can get the - lowest-density (fastest) mode with - gs "-sDEVICE=epson" -r60x72 - and the highest-density mode with - gs "-sDEVICE=epson" -r240x72. - - If you select a printer as the output device, Ghostscript also - allows you to control where the device sends its output. Normally, - output goes directly to a scratch file on Unix and VMS systems. To - send the output to a series of files foo1.xyz, foo2.xyz, ..., use - the switch - "-sOutputFile=foo%d.xyz" - The %d is a printf format specification; you can use other formats - like %02d. Each file will receive one page of output. Alternatively, - to send the output to a single file foo.xyz, with all the pages con- - catenated, use the switch - "-sOutputFile=foo.xyz" - - To find out what devices are available, type - devicenames == - after starting up Ghostscript. Alternatively, you can use the -h or -? - switch in the command line; the help message also lists the available - devices. - - To select a different paper size, use the command line switch - "-sPAPERSIZE=a_known_paper_size" - e.g., - "-sPAPERSIZE=a4" - or - "-sPAPERSIZE=legal" - - As of this printing, the known paper sizes, defined in gs_statd.ps, are: - - PAPERSIZE X" Y" X cm Y cm - ____________________________________________________ - 11x17 11" 17" 27.94 43.18 - a0 33.0556" 46.7778" 83.9611 118.816 - a10 1.02778" 1.45833" 2.61056 3.70417 - a1 23.3889" 33.0556" 59.4078 83.9611 - a2 16.5278" 23.3889" 41.9806 59.4078 - a3 11.6944" 16.5278" 29.7039 41.9806 - a4 8.26389" 11.6944" 20.9903 29.7039 - a5 5.84722" 8.26389" 14.8519 20.9903 - a6 4.125" 5.84722" 10.4775 14.8519 - a7 2.91667" 4.125" 7.40833 10.4775 - a8 2.05556" 2.91667" 5.22111 7.40833 - a9 1.45833" 2.05556" 3.70417 5.22111 - archA 9" 12" 22.86 30.48 - archB 12" 18" 30.48 45.72 - archC 18" 24" 45.72 60.96 - archD 24" 36" 60.96 91.44 - archE 36" 48" 91.44 121.92 - b0 39.3889" 55.6667" 100.048 141.393 - b1 27.8333" 39.3889" 70.6967 100.048 - b2 19.6944" 27.8333" 50.0239 70.6967 - b3 13.9167" 19.6944" 35.3483 50.0239 - b4 9.84722" 13.9167" 25.0119 35.3483 - b5 6.95833" 9.84722" 17.6742 25.0119 - flsa 8.5" 13" 21.59 33.02 - flse 8.5" 13" 21.59 33.02 - halfletter 5.5" 8.5" 13.97 21.59 - ledger 17" 11" 43.18 27.94 - legal 8.5" 14" 21.59 35.56 - letter 8.5" 11" 21.59 27.94 - note 7.5" 10" 19.05 25.4 - - Note that the B paper sizes are ISO sizes: for information about using - JIS B sizes, see `Use.htm'. - -2 Initialization_files - When looking for the initialization files (gs_*.ps), the files related - to fonts, or the file for the `run' operator, Ghostscript first tries - opening the file with the name as given (i.e., using the current - working directory if none is specified). If this fails, and the file - name doesn't specify an explicit directory or drive, Ghostscript will - try directories in the following order: - - 1. The directory/ies specified by the -I switch(es) in the command - line (see below), if any; - 2. The directory/ies specified by the GS_LIB logical, if any; - 3. The directory/ies specified by the GS_LIB_DEFAULT macro in the - Ghostscript makefile. - - Each of these (GS_LIB_DEFAULT, GS_LIB, and -I parameter) may be either - a single directory, or a list of directories separated by a `:'. - -2 X_resources - Ghostscript looks for the following resources under the program name - `Ghostscript': - - borderWidth - The border width in pixels (default = 1). - - borderColor - The name of the border color (default = black). - - geometry - The window size and placement, WxH+X+Y (default is NULL). - - xResolution - The number of x pixels per inch (default is computed from - WidthOfScreen and WidthMMOfScreen). - - yResolution - The number of y pixels per inch (default is computed from - HeightOfScreen and HeightMMOfScreen). - - useBackingPixmap - Determines whether backing store is to be used for saving display - window (default = true). - - See the file `Use.htm' for a more complete list of resources. - - To set these resources, put them in a file (such as - SYS$Login:ghostscript.dat) in the following form: - - Ghostscript*geometry: 612x792-0+0 - Ghostscript*xResolution: 72 - Ghostscript*yResolution: 72 - -2 Options - Note that VMS will convert all command line arguments to lower case - if they are not within quotes. Therefore, if a certain command does - not work, try again but with quotes around it. - - -- filename arg1 ... - Takes the next argument as a file name as usual, but takes all - remaining arguments (even if they have the syntactic form of switches) - and defines the name ARGUMENTS in userdict (not systemdict) as an - array of those strings, before running the file. When Ghostscript - finishes executing the file, it exits. - - -Dname=token - -dname=token - Define a name in systemdict with the given definition. The token must - be exactly one token (as defined by the `token' operator) and must not - contain any whitespace. - - -Dname - -dname - Define a name in systemdict with value=null. - - -Sname=string - -sname=string - Define a name in systemdict with a given string as value. This is - different from -d. For example, -dname=35 is equivalent to the - program fragment - /name 35 def - whereas -sname=35 is equivalent to - /name (35) def - - -q - Quiet startup - suppress normal startup messages, and also do the - equivalent of -dQUIET. - - -gnumber1Xnumber2 - Equivalent to -dDEVICEWIDTH=number1 and -dDEVICEHEIGHT=number2. This is - for the benefit of devices (such as X11 windows) that require (or allow) - width and height to be specified. - - -rnumber - -rnumber1Xnumber2 - Equivalent to -dDEVICEXRESOLUTION=number1 and -dDEVICEYRESOLUTION=number2 - This is for the benefit of devices (such as printers) that support - multiple X and Y resolutions. (If only one number is given, it is used - for both X and Y resolutions.) - - -Idirectories - Adds the designated list of directories at the head of the search path - for library files. - - Note that gs_init.ps makes systemdict read-only, so the values of names - defined with -D/d/S/s cannot be changed (although, of course, they can - be superseded by definitions in userdict or other dictionaries.) - -2 Special_names - - -dNOCACHE - Disables character caching. Only useful for debugging. - - -dNOBIND - Disables the `bind' operator. Only useful for debugging. - - -dNODISPLAY - Suppresses the normal initialization of the output device. This may be - useful when debugging. - - -dNOPAUSE - Disables the prompt and pause at the end of each page. This may be - desirable for applications where another program is `driving' - Ghostscript. - - -dNOPLATFONTS - Disables the use of fonts supplied by the underlying platform (e.g. - X Windows). This may be needed if the platform fonts look undesirably - different from the scalable fonts. - - -dSAFER - Disables the deletefile and renamefile operators, and the ability to - open files in any mode other than read-only. This may be desirable - for spoolers or other sensitive environments. - - -dWRITESYSTEMDICT - Leaves systemdict writable. This is necessary when running special - utility programs, but is strongly discouraged as it bypasses normal Postscript - security measures. - - -sDEVICE=device - Selects an alternate initial output device, as described above. - - -sOutputFile=filename - Selects an alternate output file for the initial output device, as - described above. - -2 Files -!!! Change - GS_Root:[Ghostscript.gs4_0] - Startup-files, utilities, and basic font definitions. - - GS_Root:[Ghostscript.Fonts4_0] - Additional font definitions. - - GS_Root:[Ghostscript.gs4_0.Examples] - Demo Ghostscript files. - - GS_Root:[Ghostscript.gs4_0.Doc] - Assorted document files. -!!! Change -2 See_also - The various Ghostscript document files (above). - -2 Bugs - See the network news group comp.lang.postscript. diff --git a/doc/gsdoc.el b/doc/gsdoc.el deleted file mode 100644 index 4f52ae06..00000000 --- a/doc/gsdoc.el +++ /dev/null @@ -1,704 +0,0 @@ -;; gsdoc.el -;; -;; GNU emacs (19.34) functions to help working with the HTML form of -;; Ghostscript documentation. -;; -;; Pete Kaiser 8 September 1998 V1.2 -;; 2 December 1999 V1.3 Correct improper "--" to "==" -;; in HTML marker comments -;;============================================================ -;; One global key setting, which runs the function to bind some keys -;; locally -- presumably in a buffer containing HTML code. Plus that -;; function itself. - -(global-set-key [?\C-\S-k] 'gskeys) - -(defun gskeys () - -"Set the keys in this buffer to use with Ghostscript HTML docs." - -(interactive) -(local-set-key [?\C-\S-b] 'gs-bold) -(local-set-key [?\C-\S-c] 'gs-code) -(local-set-key [?\C-\S-e] 'gs-emphatic) -(local-set-key [?\C-\S-g] 'gs-get-anchor) -(local-set-key [?\C-\S-h] 'gs-href) -(local-set-key [?\C-\S-i] 'gs-italic) -(local-set-key [?\C-\S-m] 'gs-mailto) -(local-set-key [?\C-\S-n] 'gs-name) -(local-set-key [?\C-\S-p] 'gs-put-anchor) -(local-set-key [?\C-\S-q] 'gs-quote) -(local-set-key [?\C-\S-r] 'gs-row-of-table) -(local-set-key [?\C-\S-s] 'gs-selfref) -(local-set-key [?\C-\S-t] 'gs-table) -(local-set-key [?\C-\S-u] 'gs-tag) -(local-set-key [?\C-\S-x] 'gs-example) -) - -;;============================================================ -;; Each of these next few functions just wraps a region in a -;; <TAG>...</TAG>, or two nested tags. Where there are two, the first one -;; is inner. See the inner function ~gsregion. - -(defun gs-bold () "Make text strong (bold)." -(interactive) -(~gsregion "b")) - -(defun gs-code () "Make text strong code (bold TT)." -(interactive) -(~gsregion "tt") -(~gsregion "b")) - -(defun gs-emphatic () "Make text emphatic (bold italic)." -(interactive) -(~gsregion "em") -(~gsregion "b")) - -(defun gs-italic () "Make text italic." -(interactive) -(~gsregion "em")) - -;;============================================================ - -(defun gs-quote () - -"Indent a region with BLOCKQUOTE and separate it with empty lines from -surrounding text." - -(interactive) - -(save-restriction (narrow-to-region (region-beginning) (region-end)) - (goto-char (point-min)) (insert "\n\n") - (push-mark (1+ (point-min)) t) - (goto-char (point-max)) - (~gsregion "blockquote") - (insert "\n\n") - ) -) - -;;============================================================ - -(defun gs-example () - -"Make an indented literatim example BLOCKQUOTE PRE and separate it with -empty lines from surrounding text." - -(interactive) - -(save-restriction (narrow-to-region (region-beginning) (region-end)) - (goto-char (point-min)) (insert "\n") - (push-mark (point-min) t) - (goto-char (point-max)) - (~gsregion "pre") - (~gsregion "blockquote") - (insert "\n") - ) -) - -;;============================================================ - -(defun gs-get-anchor () - -"Beginning at the head of this line, pick up the next anchor name for later -use along with its HTML file name. This is useful when picking up an -anchor name from a file in one buffer and using it in another buffer -containing a different file." - -(interactive) - -;; From the beginning of this line find and pick up the next non-empty -;; anchor, which might, of course not be right here -- though that's how it -;; ought to be used, to pick up an anchor for immediate use. The regular -;; expression picks up only the name itself. - -(beginning-of-line) -(re-search-forward "<a name=\"?\\([^\">]+\\)\"?></a>" nil t) -(setq gs-anchor (buffer-substring (match-beginning 1) (match-end 1))) - -;; Get the name of this buffer, treating it as the filename. - -(setq gs-anchor-file (buffer-name)) -) - -;;============================================================ - -(defun gs-href () - -"Wrap a region in an empty link and leave point in the middle of the -emptiness to write the link. Maybe some day read the URL and put it -there." - -(interactive) - -(save-restriction - (narrow-to-region (region-beginning) (region-end)) - (goto-char (point-min)) (insert "<a href=\"#\">") - (setq HREF (- (point) 2)) - (goto-char (point-max)) (insert "</a>") - (goto-char HREF) - ) -) - -;;============================================================ - -(defun gs-mailto () - -"Turn an address into a proper \"mailto:\" visually bracketed with <>." - -(interactive) - -(save-restriction - (narrow-to-region (region-beginning) (region-end)) - (setq gs-address (buffer-substring (point-min) (point-max))) - (goto-char (point-min)) (insert "<<a href=\"mailto:") - (goto-char (point-max)) (insert "\">" gs-address "</a>>") - ) -) - -;;============================================================ - -(defun gs-tag (Tag) - -"Bracket a region with some arbitrary tag read from the minibuffer, leaving -point right after the opening word of the opening tag, and the end of the -region at the end of the closing tag. Leaving point there makes it -possible, for instance, to enter additional matter in a <FONT> tag. Get to -the end of a region with ^x-^x." - -(interactive "*sTag: ") - - (~gsregion Tag) - (exchange-point-and-mark) (forward-word 1) -) - -;;============================================================ - -(defun gs-toc () - -"[Re]build the table of contents by picking up all the <Hn> lines and -converting them to properly indented <UL> entries, placing the TOC within -the standard TOC markers. Note that several of the original Ghostscript -HTML files have hand-modified TOCs, so it's wise to check before running -this function. It can be run from anywhere within the HTML file. - -This function relies on the specific format of the structure comments for -the table of contents, which are set by the g~marker function used in -defvars run when this package is loaded." - -(interactive) - -(setq g~html-buffer (buffer-name)) - -(save-restriction (save-excursion - (widen) - -;; Since we're building the TOC, delete any current TOC. Locate the place -;; for the TOC using the standard markers, deleting everything between the -;; TOC-beginning and TOC-end markers. The new TOC is built entirely in the -;; work buffer before being copied into the HTML buffer at that point. - - (goto-char (point-min)) - (search-forward g~toc-begin nil t) - (next-line 1) (beginning-of-line) (setq g~toc-insert (point)) - (search-forward g~toc-end nil t) - (beginning-of-line) (delete-region g~toc-insert (point)) - -;; Empty the work buffer by copying nothing into it. - - (copy-to-buffer gs-work-buffer 1 1) - -;; Now collect all the following header lines into a buffer to work on -;; them. The later append-to-buffer needs point to be in the middle of the -;; empty list, so go there before entering the work buffer. - - (save-excursion (while (re-search-forward "^<h[1-6][^>]*>" nil t) - (beginning-of-line) (setq BOH (point)) - (re-search-forward "</h[1-6]>\n" nil t) - (append-to-buffer gs-work-buffer BOH (point)) - )) - (goto-char g~toc-insert) - -;; All the useful header lines should be in the work buffer now. - - (save-excursion - (set-buffer gs-work-buffer) - -;; Formatting as list entries: insert <ul> when the level deepens and </ul> -;; when it rises. - - (goto-char (point-min)) - (while (search-forward "</a>" nil t) (replace-match "")) - (goto-char (point-min)) - (while (re-search-forward "</h[1-6]>" nil t) (replace-match "</a>")) - (goto-char (point-min)) - (while (re-search-forward "<a name=\"" nil t) (replace-match "<a href=\"#")) - -;; Change <h[1-6]> to <li>, inserting <ul>...</ul> as needed. Pick up the -;; upmost level from the first header, usually <h1>, and save a copy to -;; use to insert any terminating </ul>. - - (goto-char (point-min)) - (re-search-forward "^<h\\([1-6]\\)[^>]*>" nil t) - (setq First (string-to-number - (buffer-substring (match-beginning 1) (match-end 1)))) - (setq Previous First) - (replace-match "<li>" t t) - -;; Got the first one, now handle the rest. - - (while (re-search-forward "^<h\\([1-6]\\)[^>]*>" nil t) - (setq This (string-to-number - (buffer-substring (match-beginning 1) (match-end 1)))) - (setq Hold This) - (replace-match "<li>" t t) (beginning-of-line) - -;; No point being too fancy with conditionals: the "while" statements here -;; make at most one logically unnecessary test. - - (while (> This Previous) (insert "<ul>\n") (setq This (1- This))) - (while (< This Previous) (insert "</ul>\n") (setq This (1+ This))) - (setq Previous Hold) - ) - -;; Done with the loop. Clean up by inserting at the end any </ul> needed -;; to get back to the top level. - - (goto-char (point-max)) - (while (> Previous First) (insert "</ul>\n") (setq Previous (1- Previous))) - -;; Finally add the trailing whitespace and leading whitespace and header line. - - (insert "</ul></blockquote>\n\n") - (goto-char (point-min)) - (insert "\n<h2>Table of contents</h2>\n\n<blockquote><ul>\n") - -;; The TOC is now entirely built in the work buffer. Move it to where it's -;; supposed to be in the original buffer. - - (append-to-buffer g~html-buffer (point-min) (point-max)) - ) - )) -) - -;;============================================================ - -(defun gs-name () - -"Insert a name anchor at point and leave point ready to enter the anchor's -name. Anchors are always empty (that is, <a name=...></a>)." - -(interactive) - -(insert "<a name=\"\"></a>") -(backward-char 6) -) - -;;============================================================ - -(defun gs-put-anchor () - -"Insert around the current region the last anchor picked up with -gs-get-anchor. This includes the HTML file name if the href is put in a -file other than the anchor." - -(interactive) - -(save-restriction - (narrow-to-region (region-beginning) (region-end)) - (goto-char (point-min)) - (insert (concat - "<a href=\"" - -;; Insert the filename (buffer name) picked up by gs-get-anchor only if -;; this is a different buffer. - - (if (string-equal gs-anchor-file (buffer-name)) "" gs-anchor-file) - -;; And finish unconditionally with the specific anchor name. - - "#" gs-anchor "\">")) - (goto-char (point-max)) (insert "</a>")) -) - -;;============================================================ - -(defun gs-row-of-table () - -"Set up a row of a table from the line containing point. - -Insert the right things at beginning and end, and in between convert tab -and \"|\" into column breaks with a nonbreaking space in between -- which -means that no entry can contain a tab or \"|\". Format the HTML nicely -for readability. - -Between each two substantive columns this function puts a column containing -a single nonbreaking space to provide a visual break. Generally in the -first row of a table those columns should be given enough NBSPs to make -the table look right on screen and when converted to text, but this has to -be done by hand." - -(interactive) - -(save-restriction - (end-of-line) (setq EOL (point)) - (beginning-of-line) (narrow-to-region (point) EOL) - (insert "<tr valign=top>\t<td>") - (while (re-search-forward "[|\t]" nil t) - (replace-match "\n\t<td> \n\t<td>" t t)) - (goto-char (point-max)) - ) -(next-line 1) (beginning-of-line) -) - -;;============================================================ - -(defun gs-selfref () - -"Wrap an URL to make it its own link. This is useful for links that should -be visible when converted to text." - -(interactive) - -(save-restriction - (narrow-to-region (region-beginning) (region-end)) - (goto-char (point-min)) - (if (not (looking-at "http:\\|ftp:")) (insert "http://")) - (setq g~url (buffer-substring (point-min) (point-max))) - (goto-char (point-min)) - (insert "<a href=\"") - (goto-char (point-max)) (insert "\">" g~url "</a>") - ) -) - -;;============================================================ - -(defun gs-table () - -"Set up an indented table around this region, leaving plenty of white space -around the table within the HTML. The number of columns in the table is -hardcoded here as 3, so that number must be changed by hand if the table -has more than 3 columns. See gs-row-of-table for how rows are built: a -table with N visible columns generally has 2N-1 HTML columns, including the -columns that provide vertical white space." - -(interactive) - -(save-restriction - (narrow-to-region (region-beginning) (region-end)) - (indent-rigidly (region-beginning) (region-end) -80) - (goto-char (point-min)) - (insert (concat - "\n\n<blockquote><table cellpadding=0 cellspacing=0>\n" - "<tr><th colspan=3 bgcolor=\"#CCCC00\"><hr><font size=\"+1\">XXXXXXXXXX</font><hr>\n" - "<tr valign=bottom>\n" - "\t<th align=left>\n" - "\t<td> \n" - "\t<th align=left>\n" - "<tr>\t<td colspan=3><hr>\n" - )) - (goto-char (point-max)) - (insert "</table></blockquote>\n") - ) -) - -;;============================================================ - -(defun gs-text-chars () - -"Prepare text for inclusion in HTML by converting \"&\", \"<\", and \">\" into -their HTML special forms. The function acts from point to end-of-region or -end-of-buffer, whichever comes first. - -This function is NOT idempotent -- running it twice on the same text will -certainly do the wrong thing, unless at first the text contained none of -those characters." - -(interactive) -(setq BEGIN (point)) - -;; Replace significant characters: "&", "<", and ">". - -(while (search-forward "&" nil t) (replace-match "&" t t)) - -(goto-char BEGIN) -(while (search-forward "<" nil t) (replace-match "<" t t)) - -(goto-char BEGIN) -(while (search-forward ">" nil t) (replace-match ">" t t)) - -(goto-char BEGIN) -(while (search-forward "$" nil t) (replace-match "$" t t)) - -(goto-char BEGIN) -) - -;;============================================================ - -(defun gs-wrap-textfile () - -"Prepare a text file for inclusion between <pre> and </pre>, then put a -header and footer around it. One would generally run this function on a -buffer containing only an original text file; it is how the original -history and news files were first prepared. At this point it's likely to -be most useful in preparing new sections for the news document." - -(interactive) - -(widen) - -;; First prepare the entire text by replacing special characters. - -(goto-char (point-min)) -(gs-text-chars) - -;; At the end of the file, end as-is text and add the standard footer. - -(goto-char (point-max)) -(backward-word 1) (next-line 1) (beginning-of-line) -(delete-region (point) (point-max)) -(insert "\n</pre>\n") -(insert-file "Footer.htm") - -;; At the beginning of the file, begin as-is text and delete everything -;; up to the identity string (if any), saving the identity string. - -(goto-char (point-min)) -(insert "<pre>\n") (setq g~pre-point (point)) -(setq g~ID " [No pre-existing ID] ") -(if (re-search-forward (concat "^\\$" "Id:\\( [^ ]+ \\)\\$") nil t) (progn - (setq g~ID (buffer-substring (match-beginning 1) (match-end 1))) - (next-line 1) (beginning-of-line) (delete-region g~pre-point (point)) - )) - -;; Insert the standard header and fill in the identity string. - -(goto-char (point-min)) (insert-file "Header.htm") -(goto-char (point-min)) (search-forward "<!--" nil t) -(delete-horizontal-space) (insert g~ID) -(search-forward "<pre>\n" nil t) -) - -;;============================================================ - -(defun ~gsregion (Tag) - -"Tag a region, leaving point at its end and the region around the whole -thing including the new surrounding tags; thus invoking this function twice -successively makes the first invocation the inner tags and the second the -outer. - -Not intended for interactive use; for that use gs-tag, which gives a little -bit of additional service." - -(interactive) - -(if (not (= 0 (length Tag))) (save-restriction - (narrow-to-region (region-beginning) (region-end)) - (goto-char (point-min)) (insert "<" Tag ">") - (goto-char (point-max)) (insert "</" Tag ">") - (push-mark (point-min) t) - (goto-char (point-max)) - ) - ) -) - -;;============================================================ - -(defun gs-structure () - -"For historical interest only: add structuring commentary to a Ghostscript -HTML file. It's crude, but it did most of the work. Future files will -acquire their structure through plagiarism, like any other code. - -Now they've all been structured, and this function was used to do it. The -placement of table-of-contents lines never worked, because most of the -files didn't yet have TOCS. Now all files that should have TOCs have -properly placed markers, but that's history." - -(interactive) - -(setq g~thisfile (buffer-name)) - -(widen) -(goto-char (point-min)) - -;; Replace the RCS $Id if one can be found in exactly the right format, and -;; otherwise insert one just after the title, along with a warning message. - -(if (re-search-forward (concat "<!-- $" "Id: *\\([^ ]*\\) $ -->") nil t) - (progn - (setq Original (buffer-substring (match-beginning 1) (match-end 1))) - (replace-match g~thisfile t t nil 1) - ) - (progn - (search-forward "</title>" nil t) (end-of-line) - (insert (concat "\n<!-- $" "Id: " g~thisfile " $ -->")) - (setq Original "(UNSET by gs-structure)") - ) - ) - -(end-of-line) -(insert (concat "\n<!-- Originally: " Original " -->")) - -;; Place the visible header marker immediately after <BODY>. - -(re-search-forward "<body[^>]*>" nil t) - (end-of-line) (forward-char 1) - (insert (concat g~header-begin "\n\n")) - -;; Place the headline marker before the first <table> block. - -(search-forward "<table" nil t) (search-backward "\n\n" nil t) - (forward-word 1) (beginning-of-line) - (insert (concat g~headline-begin "\n\n")) - -;; After the first table block place the end-headline marker and both -;; table-of-contents markers, without worrying where the table of contents -;; really is. The TOC markers can easily be moved by hand later. - -(search-forward "\n\n" nil t) - (backward-word 1) (end-of-line) (forward-char 1) - (insert (concat - "\n" - g~headline-end "\n\n" - g~toc-begin "\n\n" - g~toc-end "\n\n")) - -;; The hints section begins with the first paragraph after where the TOC -;; markers are placed, and ends with <HR>. This isn't precise, and in fact -;; fails for several files, but once again only an approximation is needed -;; because it'll be edited by hand later. - -(search-forward "<p>" nil t) (beginning-of-line) - (insert (concat g~hint-begin "\n\n")) - -(search-forward "<hr>" nil t) (beginning-of-line) - (insert (concat g~hint-end "\n\n")) - -;; The visible header ends with (and includes) the first <HR>, and the -;; contents begin immediately thereafter. - -(search-forward "<hr>\n" nil t) - (insert (concat "\n" g~header-end "\n\n")) - -(forward-word 1) (beginning-of-line) - (insert (concat g~contents-begin "\n\n")) - -;; The contents end before the final <HR> and the trailer begins -;; immediately thereafter. - -(goto-char (point-max)) (search-backward "<hr>" nil t) - (backward-word 1) (end-of-line) (forward-char 1) - (insert (concat - "\n" - g~contents-end "\n\n" - g~trailer-begin "\n\n")) - -;; The trailer ends with </BODY>. - -(goto-char (point-max)) (search-backward "</body>" nil t) - (insert (concat "\n" g~trailer-end "\n\n")) - -;; We may have introduced trailing whitespace and extra empty lines. -;; Remove them. - -(goto-char (point-min)) -(while (re-search-forward "[ \t\240\r]+$" nil t) (replace-match "" t t)) -(goto-char (point-min)) -(while (re-search-forward "\n\n\n+" nil t) (replace-match "\n\n" t t)) - -) - -;;============================================================ -;; When this file is loaded into emacs, define the structure markers for GS -;; HTML files. These markers have two purposes: first, to make the HTML -;; more readable, and second, to enable these functions to locate sections -;; unambiguously (see gs-toc, the table of contents builder). Note that -;; the markers do not include LF. - -(defun g~marker (basic) - -"Build a complete Ghostscript HTML file marker from its text-only part. -gs-toc relies entirely on this function, so if it's ever changed, gs-toc -and existing markers would also have to be changed to keep pace. - -Intended only for initialization, not interactive use. - -All the existing files are now marked up, and since any future ones are -(properly) likely to be created by plagiarism, it's difficult to imagine -why anyone would want to change this unless they want to go to the trouble -of coming up with a much more useful marking scheme." - -(interactive) - -(setq HEAD (concat "<!-- [" basic "] ")) -(concat HEAD - (substring - "====================================================================== -->" - (- (length HEAD) 80) - )) -) - -;;============================================================ -;; Initialization code that must run after functions are defined. -;; -;; Look in a Ghostscript HTML file to see how these markers are used, -;; generally -;; -;; begin visible header -;; begin headline -;; end headline -;; begin table of contents -;; end table of contents -;; begin hint -;; end hint -;; end visible header -;; begin contents -;; end contents -;; begin visible trailer -;; end visible trailer -;; -;; although the TOC is in slightly different positions in a few files. - -(defvar g~header-begin (g~marker "1.0 begin visible header") - "Begin the HTML file's visible header material") - -(defvar g~header-end (g~marker "1.0 end visible header") - "End the HTML file's visible header") - -(defvar g~headline-begin (g~marker "1.1 begin headline") - "Begin the conspicuous headline") - -(defvar g~headline-end (g~marker "1.1 end headline") - "End the conspicuous headline") - -(defvar g~toc-begin (g~marker "1.2 begin table of contents") - "Begin the table of contents") - -(defvar g~toc-end (g~marker "1.2 end table of contents") - "End the table of contents") - -(defvar g~hint-begin (g~marker "1.3 begin hint") - "Begin the \"for other information\" section") - -(defvar g~hint-end (g~marker "1.3 end hint") - "End the \"for other information\" section") - -(defvar g~contents-begin (g~marker "2.0 begin contents") - "Begin the main contents") - -(defvar g~contents-end (g~marker "2.0 end contents") - "End the main contents") - -(defvar g~trailer-begin (g~marker "3.0 begin visible trailer") - "Begin the visible standard trailer material") - -(defvar g~trailer-end (g~marker "3.0 end visible trailer") - "End the visible standard trailer material") - -;;============================================================ -;; Some working variables - -(defvar gs-anchor "JUNK" "*Anchor name to insert") -(defvar gs-anchor-file "JUNKFILE" "*Anchor filename to insert") -(defvar gs-work-buffer "*GS work*" "*Ghostscript working buffer") diff --git a/doc/images/.DS_Store b/doc/images/.DS_Store Binary files differdeleted file mode 100644 index 5008ddfc..00000000 --- a/doc/images/.DS_Store +++ /dev/null diff --git a/doc/images/Artifex_logo.png b/doc/images/Artifex_logo.png Binary files differdeleted file mode 100644 index ced5b8e6..00000000 --- a/doc/images/Artifex_logo.png +++ /dev/null diff --git a/doc/images/favicon.png b/doc/images/favicon.png Binary files differdeleted file mode 100644 index 09975d82..00000000 --- a/doc/images/favicon.png +++ /dev/null diff --git a/doc/images/ghostscript_logo.png b/doc/images/ghostscript_logo.png Binary files differdeleted file mode 100644 index b47f2f04..00000000 --- a/doc/images/ghostscript_logo.png +++ /dev/null diff --git a/doc/images/hamburger-light.png b/doc/images/hamburger-light.png Binary files differdeleted file mode 100644 index 79d22a15..00000000 --- a/doc/images/hamburger-light.png +++ /dev/null diff --git a/doc/images/icon-search.png b/doc/images/icon-search.png Binary files differdeleted file mode 100644 index efcadaf8..00000000 --- a/doc/images/icon-search.png +++ /dev/null diff --git a/doc/images/x-light.png b/doc/images/x-light.png Binary files differdeleted file mode 100644 index 2fab8ee5..00000000 --- a/doc/images/x-light.png +++ /dev/null diff --git a/doc/index.htm b/doc/index.htm new file mode 100644 index 00000000..61364372 --- /dev/null +++ b/doc/index.htm @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="refresh" content="3; url='https://ghostscript.readthedocs.io'" /> + </head> + <body> + <p>Please find the latest documentation on <a href="https://ghostscript.readthedocs.io">ghostscript.readthedocs.io</a>.</p> + </body> +</html>
\ No newline at end of file diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index c523e40a..00000000 --- a/doc/index.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> -<meta http-equiv="content-type" content="text/html; charset=us-ascii"> -<title>Ghostscript</title> -<!-- Ghostscript auto-referral to the introductory document --> -<meta http-equiv="REFRESH" content="0; url=Readme.htm"> -<link href="default.css" rel="stylesheet" type="text/css"> -</head> - - -<body> - <header><h1>Ghostscript documentation</h1></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> - -<!--START EDITING HERE--> -Please see <a href="Readme.htm">Readme.htm</a> for an index of the -Ghostscript documentation. - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> -</body> -</html> diff --git a/doc/index.js b/doc/index.js deleted file mode 100644 index a2760ef2..00000000 --- a/doc/index.js +++ /dev/null @@ -1,10 +0,0 @@ -$( "#sidebar" ).before( "<div class='menuTrigger'></div>" ); - -$(this).show; -$('.menuTrigger').click(function() { - $(this).toggleClass('selected'); - $('#sidebar').slideToggle( "slow", function() { - - }); - -});
\ No newline at end of file diff --git a/doc/language-bindings/c-sharp-ghost-api.html b/doc/language-bindings/c-sharp-ghost-api.html index b67442d4..935f52ee 100644 --- a/doc/language-bindings/c-sharp-ghost-api.html +++ b/doc/language-bindings/c-sharp-ghost-api.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/language-bindings/c-sharp-ghost-mono.html b/doc/language-bindings/c-sharp-ghost-mono.html index 0d4380d2..e71a94ef 100644 --- a/doc/language-bindings/c-sharp-ghost-mono.html +++ b/doc/language-bindings/c-sharp-ghost-mono.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/language-bindings/c-sharp-ghost-net.html b/doc/language-bindings/c-sharp-ghost-net.html index 69af7316..d0da9454 100644 --- a/doc/language-bindings/c-sharp-ghost-net.html +++ b/doc/language-bindings/c-sharp-ghost-net.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/language-bindings/c-sharp-intro.html b/doc/language-bindings/c-sharp-intro.html index a9f6e5ad..76309443 100644 --- a/doc/language-bindings/c-sharp-intro.html +++ b/doc/language-bindings/c-sharp-intro.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> @@ -192,7 +192,7 @@ <p>Below is a screenshot of the sample application with a PDF open:</p> <p><img src="images/ghostnet-wpf-example.png" alt="ghostnet wpf example UI"></p> <h2 id="ghostmono">GhostMono</h2> -<p><code>GhostMono</code> is the <a href="https://www.mono-project.com/">Mono</a> equivalent of <code>GhostNET</code> and as such has no dependancy on a Windows environment.</p> +<p><code>GhostMono</code> is the <a href="https://www.mono-project.com/">Mono</a> equivalent of <code>GhostNET</code> and as such has no dependency on a Windows environment.</p> </article> </div> diff --git a/doc/language-bindings/demo-code.html b/doc/language-bindings/demo-code.html index 7b71c2db..4d3641fb 100644 --- a/doc/language-bindings/demo-code.html +++ b/doc/language-bindings/demo-code.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/images/favicon.svg b/doc/language-bindings/images/favicon.svg index 86b60ff9..86b60ff9 100644 --- a/doc/images/favicon.svg +++ b/doc/language-bindings/images/favicon.svg diff --git a/doc/language-bindings/index.html b/doc/language-bindings/index.html index 3a793b1e..36ffee8a 100644 --- a/doc/language-bindings/index.html +++ b/doc/language-bindings/index.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/language-bindings/java-gsjavajar.html b/doc/language-bindings/java-gsjavajar.html index 68877f48..baeda74a 100644 --- a/doc/language-bindings/java-gsjavajar.html +++ b/doc/language-bindings/java-gsjavajar.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/language-bindings/java-intro.html b/doc/language-bindings/java-intro.html index cb625833..e7344876 100644 --- a/doc/language-bindings/java-intro.html +++ b/doc/language-bindings/java-intro.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> @@ -168,7 +168,7 @@ integer types. The build scripts expect an include folder relative to their loca </tbody></table> <blockquote> <p><strong>NOTE</strong><br> -<code>gsjava</code> has a dependancy on <a href="#jni-building-the-java-native-interface">jni</a>, please ensure that <code>gs_jni</code> is able to be built beforehand.</p> +<code>gsjava</code> has a dependency on <a href="#jni-building-the-java-native-interface">jni</a>, please ensure that <code>gs_jni</code> is able to be built beforehand.</p> </blockquote> <h4 id="building-with-eclipse">Building with Eclipse</h4> <p>Alternatively you can use <a href="https://www.eclipse.org/eclipseide/">Eclipse</a> to build the JAR file.</p> diff --git a/doc/language-bindings/md/c-sharp-intro.md b/doc/language-bindings/md/c-sharp-intro.md index 87722021..b6da28f0 100644 --- a/doc/language-bindings/md/c-sharp-intro.md +++ b/doc/language-bindings/md/c-sharp-intro.md @@ -79,7 +79,7 @@ Below is a screenshot of the sample application with a PDF open: ## GhostMono -`GhostMono` is the [Mono] equivalent of `GhostNET` and as such has no dependancy on a Windows environment. +`GhostMono` is the [Mono] equivalent of `GhostNET` and as such has no dependency on a Windows environment. [Visual Studio]: https://visualstudio.microsoft.com diff --git a/doc/language-bindings/md/java-intro.md b/doc/language-bindings/md/java-intro.md index fe6422fa..a9d5f517 100644 --- a/doc/language-bindings/md/java-intro.md +++ b/doc/language-bindings/md/java-intro.md @@ -101,7 +101,7 @@ Navigate to `ghostpdl/demos/java/gsjava` and use the following: |Linux| `build_linux.sh` | > **NOTE**<br> -> `gsjava` has a dependancy on [jni], please ensure that `gs_jni` is able to be built beforehand. +> `gsjava` has a dependency on [jni], please ensure that `gs_jni` is able to be built beforehand. #### Building with Eclipse diff --git a/doc/language-bindings/python-gsapi.html b/doc/language-bindings/python-gsapi.html index 0638ba56..337f769b 100644 --- a/doc/language-bindings/python-gsapi.html +++ b/doc/language-bindings/python-gsapi.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/language-bindings/python-intro.html b/doc/language-bindings/python-intro.html index 338ff1e4..63cff74d 100644 --- a/doc/language-bindings/python-intro.html +++ b/doc/language-bindings/python-intro.html @@ -4,7 +4,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="../images/favicon.svg"> + <link rel="shortcut icon" href="images/favicon.svg"> <link href="css/default.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="js/default.js"></script> </head> diff --git a/doc/pscet_status.txt b/doc/pscet_status.txt deleted file mode 100644 index e136d20a..00000000 --- a/doc/pscet_status.txt +++ /dev/null @@ -1,5415 +0,0 @@ -# Report of Ghostscript's conformance against the Quality Logic CET suite -# -Test Status Comments - -08-04- AOK This test is intentionally printer specific and is for information - only. Ghostscript completes all pages properly. - -09-01-1 OK Fixed with gs_cet.ps initialization file - Default initial condition differs for currentblackgeneration and the - type and global of the default procedure differ. - -09-01-2 OK Verified visually against Tek hardcopy. RJJ - matches CPSI. - -09-02-1 OK Fixed rev 7102. RJJ - -09-02-2 OK Colors corrected by rev 7172, fixed by rev. 7201 - -09-02-3 OK Corrected by 7152 and 7162. ADC - -09-02-4 OK Corrected by 7152 and 7162. ADC - -09-02-5 OK - -09-03-1 OK Fixed rev 7102. RJJ - cpsi/09-03-1 is bogus. Acrobat 7 output obtained. - -09-03-2 OK Fixed rev 7102. RJJ - cpsi/09-03-2 missing. Acrobat 7 output obtained. - -09-03-3 OK Fixed by rev. 7202 - -09-03-4 OK Fixed rev 7102. RJJ - cpsi/09-03-4 missing. Acrobat 7 output obtained. - -09-03-5 OK Verified visually against Tek hardcopy. RJJ - cpsi/09-03-5 missing. Acrobat 7 output obtained. - -09-03-6 OK Verified visually against Tek hardcopy. RJJ - cpsi/09-03-6 missing. Acrobat 7 output obtained. - -09-03-7 OK Verified visually against Tek hardcopy. RJJ - cpsi/09-03-7 missing. Acrobat 7 output obtained. - -09-03-8 OK Fixed rev 7159. - cpsi/09-03-8 missing. Acrobat 7 output obtained. - -09-03-9 OK - cpsi/09-03-9 missing. Acrobat 7 output obtained. - -09-04-1 OK - -09-04-2 OK - -09-05-1 DIFF Device Dependent: GS, CPSI and Tek hardcopy all different. - probably can be made "closer" using gs_cet.ps assign Ray. - -09-05-2 OK Device Dependent: GS matches Tek hardcopy. RJJ - -09-05-3 OK Device Dependent: GS matches Tek hardcopy. RJJ - -09-05-4 OK Device Dependent: GS matches Tek hardcopy. RJJ - -09-05-5 OK Device Dependent: GS matches Tek hardcopy. RJJ - -09-05-6 OK Device Dependent: GS matches Tek hardcopy after fixed by rev. 7203 - (CPSI much different) - -09-05-7 OK Device Dependent: GS matches Tek hardcopy. RJJ - -09-05-8 OK - -09-06-1 OK Fixed in rev. 7162. - Alex and RJJ - -09-06-2 OK Fixed in rev. 7162. - Alex and RJJ - -09-06-3 OK Fixed rev. 7159 and 7162. - Alex and RJJ - -09-06-4 OK Fixed in rev. 7162. - Alex and RJJ - -09-06-5 OK Fixed in rev. 7162. - Alex and RJJ - -09-07-1 OK Rev. 7207 changes Ghostscript to match Tek. - The attributes of the arrays returned by currentcolortransfer - vary between PS interpreters. PLRM doesn't require any - particular attributes. Initial graphic state is created by an OEM, - not Adobe. - -09-07-2 OK - -09-07-3 OK - -09-07-4 OK - -09-08-1 OK Fixed in rev. 7207 - -09-08-2 OK - -09-08-3 OK - -09-09-1 OK Device Dependent: GS matches Tek hardcopy. CPSI always uses setflat == 1. - GS clamps setflat value minimum as 0.2 and maximum at 100.0 same as Tek. - -09-09-2 OK Device Dependent: GS matches Tek hardcopy. CPSI always uses setflat == 1. - GS clamps setflat value minimum as 0.2 and maximum at 100.0 same as Tek. - -09-09-3 OK - -09-10-1 OK Fixed rev 7102. RJJ - -09-10-2 OK "0" vs. "0.0" is fixed in rev. 7186. - -09-10-3 OK Fixed rev 7102. RJJ - -09-10-4 OK Colors corrected by rev 7172. - -09-10-5 OK - -09-11-1 AOK GS has different small numbers near zero (e-5) than CPSI Tek has 0.0 - -09-11-2 OK Corrected by revision 7162 (Alex). - ADC - -09-11-3 OK Minor differences visually reviewed by RJJ - -09-11-4 OK - -09-11-5 AOK Implementation dependent: Tek and CPSI and GS all different. GS does - match 09-11-7 (Test B3) as the test comments state. - -09-11-6 OK - -09-11-7 AOK Implementation dependent: Tek and CPSI and GS all different. GS does - match 09-11-5 (Test B1) as the test comments state. - -09-11-8 OK - -09-11-9 OK - -09-12-1 AOK Device Dependent. Every device has its own initial halftone. - Rev. 7208 makes currenthalftone return a read-only dictionary. - Adding a HalftoneType 9 as the Default entry to Resource/Halftone - path allows us to match Tek. Halftone isn't used with contone anyway. - -09-12-2 AOK Device Dependent, Resolution dependent. Tek and CPSI differ - GS matches Tek hardcopy for SYNTAX 1 at 300dpi, SYNTAX 2 - GS prints /Angle = 0, Tek shows /Angle = 0.0 - -09-12-3 OK GS matches Tek hardcopy. CPSI much different. - -09-12-4 OK Resolution and Orientation dependent: GS matches Tek hardcopy at 300 - dpi landscape. - -09-12-5 OK GS at 300 dpi matches Tek hardcopy and checksum. Resolution dependent. - -09-12-6 OK Resolution and Orientation dependent: GS matches Tek hardcopy at 300 - dpi landscape. - -09-12-7 OK Resolution and Orientation dependent: GS matches Tek hardcopy at 300 - dpi landscape. - -09-12-8 OK GS matches Tek hardcopy. CPSI much different. - -09-12-9 OK - -09-13-1 OK Fixed rev 7102. RJJ - -09-13-2 OK Fixed again by rev 7215 after rev 7124 caused problem. Matches Tek - harcopy. - -09-13-3 OK Fixed rev 7102. RJJ - -09-13-4 OK - -09-13-5 OK - -09-14-1 OK Minor differences visually reviewed by RJJ - -09-14-2 OK - -09-15-1 OK Minor differences visually reviewed by RJJ - -09-15-2 OK - -09-16-1 OK - -09-16-2 OK - -09-16-3 OK - -09-17-1 OK - -09-17-2 OK - -09-17-3 OK - -09-18-1 OK - -09-18-2 OK - -09-19-1 OK Fixed rev 7102. RJJ - -09-19-2 OK GS matches Tek hardcopy. CPSI gives 0.63 'B' value on first line of - third group -- Tek is probably correct. "0" vs. "0.0" is fixed in rev. 7186. - -09-19-3 OK Fixed rev 7102. RJJ - -09-19-4 OK - -09-19-4 OK - -09-19-5 OK - -09-20-1 AOK Device Dependent: different default screen (OK) - GS matches Tek on the rest. - -09-20-2 OK Device Dependent: Matches Tek hardcopy and checksum. RJJ - -09-20-3 OK Device Dependent: Matches Tek hardcopy and checksum. RJJ - -09-20-4 DIFF Device Dependent, Resolution dependent. Tek and CPSI differ - GS almost matches Tek hardcopy except "Actual Angle" when - AccurateScreens=true is 100.6 for GS (100.0 for Tek) and - GS shows "100 27" instead of "100.0 27.0" Assign: Ray - -09-20-5 OK - -09-21-1 OK - -09-21-2 OK - -09-21-3 OK - -09-22-1 OK Rev. 7207 changes Ghostscript to match Tek. - See 09-07-01 for details. - -09-22-2 OK - -09-22-3 OK - -09-22-4 OK - -09-23-1 OK Fixed by gs_cet.ps RJJ - -09-23-2 OK - -09-24-1 OK - -09-24-2 OK Fixed by rev 7617. - -09-24-3 OK Fixed by r7123. - -09-24-4 OK - -09-25-1 OK - -09-25-2 OK Fixed by rev 7617. - -09-25-3 OK Fixed by r7123. - -09-25-4 OK - -09-26-1 OK Minor differences visually reviewed by RJJ - -09-26-2 OK Fixed by rev 7617. - -09-26-3 OK Fixed by r7123. Color corrected by rev 7172. - -09-26-4 OK - -09-27-1 AOK GS has different small numbers near zero (e-5) than CPSI Tek has 0.0 - Device Dependent. - -09-27-2 OK Minor differences visually reviewed by RJJ - -09-27-3 OK Fixed by rev 7617. - -09-27-4 OK Fixed by r7123. Color corrected by rev 7172. - -09-27-5 OK - -09-28-1 AOK Ghostscript is different from both Tek and PhotoPrint but - matches Distiller 5. Tek doesn't reset the dash array at - initgraphics. PhotoPrint redefines halftone operators as no-op, - which affects the test results. Fixed by rev. 7792. - Alex - -09-28-2 OK Fixed as of rev. 7211 - -09-28-3 OK Fixed by rev 7617. - -09-28-4 OK Imagemask -- Fixed by r7123. Tek and AD7 output differ. - -09-28-5 OK Matches Tek hardcopy output. RJJ - -09-29-1 AOK Device Dependent: GS has ProcessColorModel /DeviceRGB, Tek has non-standard - /DeviceCMY. GS matches Tek if BG, UCR set the same and ProcessColorModel is - forced to /DeviceCMY. CPSI shows ProcessColorModel /DeviceN. DeviceRGB - values fixed in rev. 7216 - -09-29-2 OK Fixed by rev 7617. - -09-29-3 OK Imagemask -- Fixed by r7123. Tek and AD7 output differ. - -09-29-4 OK - -09-30-1 OK Colors corrected by rev 7172. - -09-30-2 OK Error reports are fixed in rev. 7138. - Alex - -09-30-3 OK Colors corrected by rev 7172. Fixed by rev 7617. - -09-30-4 OK Fixed by r7123. Color corrected by rev 7172. - -09-30-5 OK - -09-31-1 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-1 bogus. Acrobat 7 output obtained. - -09-31-10 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-10 missing. Acrobat 7 output obtained. - -09-31-2 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-2 missing. Acrobat 7 output obtained. - -09-31-3 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-3 missing. Acrobat 7 output obtained. - -09-31-4 AOK GS Matches Acrobat 7 output. Tek output has small dark rectangles - that are not correct. - cpsi/09-31-4 missing. Acrobat 7 output obtained. - -09-31-5 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-5 missing. Acrobat 7 output obtained. - -09-31-6 OK Fixed revs 7159 and 7187. - NOTE: AD7 gets limitcheck as pre-7159 GS and matches that GS output. - cpsi/09-31-6 missing. Acrobat 7 output obtained. - -09-31-7 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-7 missing. Acrobat 7 output obtained. - -09-31-8 OK Fixed by rev 7617. - cpsi/09-31-8 missing. Acrobat 7 output obtained. - -09-31-9 OK Matches Tek hardcopy output. RJJ - cpsi/09-31-9 missing. Acrobat 7 output obtained. - -09-32-1 OK Verified visually against Tek hardcopy by Sabrina / RJJ - cpsi/09-32-1 missing. Acrobat 7 output obtained. - -09-32-2 OK Error codes are adjusted to match the checksum. rev. 7167 - Alex - cpsi/09-32-2 missing. Acrobat 7 output obtained. - -09-32-3 OK Fixed by rev 7617. - cpsi/09-32-3 missing. Acrobat 7 output obtained. - -09-32-4 OK Matches Tek hardcopy output. RJJ - cpsi/09-32-4 missing. Acrobat 7 output obtained. - -09-32-5 OK Verified visually against Tek hardcopy by Sabrina / RJJ - cpsi/09-32-5 missing. Acrobat 7 output obtained (but differs). - -09-33-1 OK - -09-33-2 OK Matches Tek hardcopy output. RJJ - -09-33-3 OK Fixed by rev 7617. - -09-33-4 OK Fixed by r7123. Color corrected by rev 7172. - -09-33-5 OK Fixed rev. 7217 - -09-34-1 OK Matches Tek hardcopy output. RJJ - -09-34-10 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-10 missing - -09-34-11 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-11 missing - -09-34-12 AOK GS has smooth gradients, Tek hardcopy has dark gray stripe up - middle of gradients. GS matches AD7 - I found that once I set embedded an sRGB colorrendering - dictionary, which is what AD7 uses for RGB matching, - GS and AD7 were nearly a perfect match. There was only - one relatively small rectangle area pointed out by cmpi in a - single ramp ( the CIEDefg [ffff] row). It appears that the TEK - output is the one that is incorrect. TIM - cpsi/09-34-12 missing - -09-34-13 OK Fixed revs 7159 and 7187. - cpsi/09-34-13 missing - -09-34-14 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-14 missing - -09-34-15 AOK Mostly matches Tek hardcopy output. GS has smooth gradients, Tek - has dark gray stripe in middle of 8th row. GS matched AD7 - -- - In my tests with GS, AD5 as well as the AD7 output, none show - the dark gray stripe mentioned. It is my opinion that TEK is the - one that is failing. TIM - cpsi/09-34-15 missing - -09-34-16 AOK GS missing some graphics seen on Tek hardcopy. - Probably RGB vs. CMYK device color - RJJ. - I do not understand Ray's comment. Using the ppmraw device, I - see all of the graphics at the right side of the page. Please - note that the appearance of this page depends upon the process - color model of the output device. The page uses spot colors. - Thus the appearance of the page depends upon how the device - treats spot colors. One of the spot color is called C1 and it - is white. The C1 spot color is printed on top of the lower four - graphics. Thus if the output device supports spot colors then - this results in a white appearance for this section of the page. - The GS tiffsep device (which supports spot colors) shows this - section of the page as being white. The tiffsep device also - produces a separation for the C1 spot color which shows the area - covered by this ink. Devices which do not support spot colors - use the tint transform function to convert the spot colors into - process colors. Logically the tint tranform functions should - produced the same appearance as the spot colors. However this is - not the case with this page. Thus devices which do not support - spot colors such as the ppmraw (process color model = DeviceRGB) - or the tiff32nc (device process color = DeviceCMYK only) use the - tint transform functions are producing different appearances. - The same effect can be seen with Distiller/Acrobat 7.0. The - presence of the spot colors can be examined with the 'Output - Preview' feature. Disabling the 'Overprint Preview' changes - the process color model of Acrobat to DeviceRGB. This forces - the use of the tint transform functions by Acrobat. The - 'missing' graphics then appear. - cpsi/09-34-16 missing - -09-34-17 OK Fixed by rev 7617. - cpsi/09-34-17 missing - -09-34-18 OK Fixed by r7123. - cpsi/09-34-18 missing - -09-34-19 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-19 missing - -09-34-2 AOK GS has Yellow graphic, Tek shows Red for 'SeparateUnBlue setcolorspace' - (right of "1.0" text). Probably RGB vs. CMYK device color - NOTE: AD7 and Tek hardcopy output differ in same areas. - RJJ - Distiller/Acrobat 7.0 differ on four graphics. These are the five below - the text that says "( /HIVAL 4095 def )". Distiller/Acrobat shows the - first four of these as a grayish shade. The fifth is a paler shade of - gray. GS shows these as black, gray, burgandy, brown, and red respectively. - - ADC. - From what I can see the yellow graphic that GS creates is - correct. The color space is aptly named "SeparateUnblue" (see - further below), since "un-blue" is yellow, this lead me to - believe yellow is what should be produced. Upon further digging - into the color space and putting some debug messages in the - tintTransform procedure, it also seems to be correct. From what - I can see the tint tintTransform procedure takes the blue value - and does some math on it to vary it in the range of 0.0 to 1.0. - It also places two ones on the stack just ahead of this blue - value so that all values passed to the /DeviceRGB are in the - range 1,1,0 to 1,1,1, which are various shades of yellow. - -- - When I first did this I didn't know about the AD7 output... This - further verifies that the yellow is correct as AD7 matches GS - for this part of the job. - -- - There is a second unresolved issue below the section that says - "/HIVAL 4095 def". I believe again that the four non-matching - graphics produced by GS are correct. For example... - -- - The burgandy and brown are produced by the following code, respectively: - /HIVAL 4095 def - ... - (gs Indexed_RGB_Proc setcolorspace 2048 setcolor Q) - (gs Indexed_RGB_Proc setcolorspace 3072 setcolor Q) - With the following colorspace definition: - /Indexed_RGB_Proc - { - [ - /Indexed - /DeviceRGB - HIVAL - { - dup - HIVAL - div - exch - HIVAL - 2 - idiv - dup - 2 - index - exch - mod - exch - div - exch - HIVAL - 3 - idiv - dup - 3 - -1 - roll - exch - mod - exch - div - } - ] - } - def - -- - Basically this space produces as output RGB values where the B's - that are split into 3 ranges by B_out= ( Value_in mod (HIVAL/3) - ) / (HIVAL/3), G's that are split into 2 ranges by G_out = - (Value_in mod (HIVAL/2) ) / (HIVAL/ 2) and the R's are in one - range by R_out = Value_in / HIVAL. So a input value of 1/2 of - the input range (determined by HIVAL) produces an output of - roughly R=0.5, G=0, B=0.5. An input value of .75 of the input - range produces and output of roughly R=.74,G=.5,B=.25 - -- - I modified the colorspace to dump the stack at the end of its - number crunching tintTransform procedure. I printed out the - values for the burgandy and brown graphic sections and here is - what I got back. - -- - 2048 setcolor - 0.500366 // B - 0.00048852 // G - 0.500122 // R - Which is the burgandy color mentioned. - -- - 3072 setcolor - 0.250549 // B - 0.500733 // G - 0.750183 // R - Which is the brown color mentioned. - This verified to me that GS is doing the right thing. TIM - cps/09-34-2 missing - -09-34-3 AOK GS RGB has missing graphic, Tek shows Cyan for 'SeparateUncyan setcolorspace' - (right of "1.0" text). GS matches Tek if Cyan, Magenta, Yellow and Black - Separation colorspaces are known, as with the 'tiffsep' device. A printer - that is CMYK will usually have the Separations available for overprint - effects. RJJ - - - NOTE: AD7 and Tek hardcopy output differ in same areas. RJJ - GS produces output matching Tektronix if 'tiffsep' device since this - device does not use the tint transform on /Cyan separation used in the - SeparationUncyan section. - - - The 'SeparateUncyan' issue is another example of a separation color space - which (intentionally ?) has a tint transform function which produces different - colors when it is used. Thus the output depends upon whether or not the tint - transform function is used. This can be seen by disabling the 'Overprint - Preview' feature in Acrobat 7.0. GS produces results which are consistent with - Acrobat for both cases. (this is expected). ADC - cpsi/09-34-3 missing - -09-34-4 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-4 missing - -09-34-5 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-5 missing - -09-34-6 AOK GS matches graphics colors, but the code equivalent to - /Pattern setcolorspace 16 16 true matrix { (jihad) } imagemask - leaves imagemask operands on the stack on Adobe interpreters. - This is an obvious bug that we don't want in Ghostscript. - cpsi/09-34-6 missing - -09-34-7 AOK GS has different 'currentcolor' results and different color graphics - Probably RGB vs. CMYK device color - NOTE: AD7 and Tek hardcopy output differ in same areas. - RJJ - There are two issues with this page. The first issue is the colors of - of the various graphics on the page. The page has spot colors. It - also has tint transform functions which do not provide logically - consistent results. Thus the appearance of the graphics depend upon - if the tint transform functions are being used. The results with GS - match the results from Acrobat 7.0 as expected. - The second issue (which is a problem) is that the currentcolor value - for the CIEBasedDEFG differs. The graphic for the same line is also - missing (which is probably related.) - ADC - -- - The differences were releated to the colorrendering dictionary - in use. When I embedded an sRGB CRD the output matched AD5/AD7. TIM - cpsi/09-34-7 missing - -09-34-8 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-8 missing - -09-34-9 OK Matches Tek hardcopy output. RJJ - cpsi/09-34-9 missing - -09-35-1 OK Matches Tek hardcopy output. RJJ - -09-35-2 OK Color difference (cmpi -c25 is OK, -c24 detects all pixels differ), - otherwise fixed by rev 7617. - Presumed to match Tek (different inks, etc.) since this test uses - 'setcolortransfer' which is ignored by CPSI. RJJ - -09-35-3 OK Fixed by r7123. - -09-35-4 OK Minor color difference. - -09-36-1 OK Minor differences visually reviewed by RJJ - -09-36-2 OK Minor differences visually reviewed by RJJ - -09-36-3 OK Fixed by rev. 7226 - -09-36-4 NF Dash pattern differences with GS. - Analyzed by Igor. - - - GS rounds coordinates to 1/256th of a pixel. - Due to that, when a curve is converted into a polygon, - its vertices are rounded, and therefore the length - of the polygon becomes few bigger than the ideal polygon. - Then applying the dash, it covers a smaller part - of the polygon than with CPSI. - - - One possible solution is : - Add floating coordinates to path segments. - The floating coordinates duplicate fixed ones, - and used only for computing the segment length. - The old fixed coordinated are used for anything else - as they do now. - -09-36-5 DIFF In "Technical Paths", Ghostscript differs a lot, combination - of 09-24-2 linecap linejoin issues and dash issues. Defer - this until after 09-24-2 is addressed. - Need CPSI for investigations. - Assign: Ray - -09-36-6 OK Fixed by r7123. - -09-36-7 OK Fixed as of r7500. - -09-37-1 AOK GS similar to Tek, but the value at which polygon edges changes from - 16 to 8 differs (GS at 53, Tek at 19). Also Tek changes from 'smooth' - to 16 at 5, GS at 13. CPSI fixed to implement setflat changes from - smooth to 16 sides at 9 (GS at 13), CPSI never has less than 16 sides. - Resolution dependent (spec is 'output device pixels') and PLRM 3rd ed - states "If the flatness parameter is large enough to cause visible - straight line segments to appear, the result is unpredictable." - When GS is run at 300 dpi (same resolution as Tek), the transition - from smooth to 16 sides is at 7 (vs. 5 on the Tek) and from 16 to 8 - sides at 27 (vs. 19 on the Tek). - - - Since Tek and CPSI differ, and GS generally uses more line segments, - the GS output conforms and is superior to the Tek output. - -09-37-10 OK GS matches Tek and CPSI output now matches Tek (12/04/06). - Imagemask turkey fixed by r7123. - -09-37-11 OK Matches Tek hardcopy output. RJJ - -09-37-2 OK Matches Tek hardcopy output. RJJ - -09-37-3 OK Matches Tek hardcopy output. RJJ - -09-37-4 AOK GS similar to Tek, but the value at which polygon edges changes to - very coarse differs (GS at 73, Tek at 23). Also Tek changes from 'smooth' - to bumpy at 5, GS at 19. When GS is run at 300 dpi, the transitions - from smooth to bumpy is at 11, and from bumpy to very coarse at 39. - Resolution dependent (spec is 'output device pixels'). CPSI fixed to - implement setflat transitions to bumpy at 13 and to coarse at 33. - - - Since Tek and CPSI differ, and GS generally uses more line segments, - the GS output conforms and is superior to the Tek output. - -09-37-5 OK Matches Tek hardcopy output. RJJ - -09-37-6 OK Very small fill differences. RJJ - -09-37-7 OK Very small fill differences. RJJ (CPSI ignores setflat, GS - similar to Tek hardcopy) - -09-37-8 DIFF GS similar to Tek, but GS differs in the exact polygon shapes. - Resolution dependent (spec is 'output device pixels'). GS at 300 - dpi has less edges on large outline in top two images. CPSI (at - 600 dpi) also smoother than GS on top two outlines. - assign: Ray - -09-37-9 DIFF "Stroked_Objects" and "Filled_Objects" differ slightly with - number of polygonal edges. Tek shows strokepath of "Technical - Paths" IS subject to setflat -- GS has smoother round cap/join. - Resolution dependent (spec is 'output device pixels'). CPSI fixed - to implement setflat matches Tek ouptut for "Technical paths". - Assign: Ray - -09-38-1 OK Minor differences visually reviewed by RJJ - -09-38-2 OK Fixed by rev 7617. - -09-38-3 OK Fixed by r7123. - -09-38-4 OK - -09-39-1 OK Matches Tek hardcopy output. RJJ - -09-39-2 OK matches CPSI - -09-39-3 OK matches CPSI. Imagemask fixed by r7123. - -09-39-4 OK - -09-40-1 AOK Matches Tek hardcopy output. RJJ (CPSI ignores settransfer) - GS is contone, Tek is dithered - -09-40-10 OK - -09-40-11 OK - -09-40-12 OK - -09-40-13 OK - -09-40-14 OK - -09-40-15 OK - -09-40-16 OK - -09-40-17 OK - -09-40-18 OK - -09-40-19 OK Matches Tek hardcopy output. RJJ (CPSI ignores settransfer) - -09-40-2 AOK GS is contone, Tek is dithered, otherwise GS matches Tek. - CPSI ignores transfer function. - -09-40-20 OK Minor differences visually reviewed by RJJ - -09-40-21 AOK GS and Tek give 'rangecheck' for last three "Test I". GS - matches Tek except GS is contone, Tek is dithered. - -09-40-22 OK - -09-40-23 OK Fixed by rev 7617. - -09-40-24 OK Fixed by r7123. Color corrected by rev 7172. - -09-40-25 OK - -09-40-3 OK - -09-40-4 OK - -09-40-5 OK - -09-40-6 OK - -09-40-7 OK - -09-40-8 OK GS matches Tek since rev. 7168 - Alex - -09-40-9 OK - -09-41-1 OK - -09-41-2 OK Fixed by rev 7617. - -09-41-3 OK Fixed by r7123. - -09-41-4 OK Fixed by r7124. - -09-42-1 OK - -09-42-2 OK - -09-42-3 OK Minor differences visually reviewed by RJJ - -09-42-4 OK - -09-42-5 OK Fixed by rev 7617. - -09-42-6 OK Fixed by r7123. - -09-42-7 OK - -09-43-1 OK - -09-43-2 OK - -09-43-3 OK Minor differences visually reviewed by RJJ - -09-43-4 OK - -09-43-5 OK Fixed by rev 7617. - -09-43-6 OK Fixed by r7123. - -09-43-7 OK - -09-44-1 OK Minor differences visually reviewed by RJJ - -09-44-2 OK - -09-44-3 OK Minor differences visually reviewed by RJJ - -09-44-4 OK - -09-44-5 OK Fixed by rev 7617. - -09-44-6 OK Fixed by r7123. - -09-44-7 OK - -09-45-1 OK - -09-45-2 OK - -09-45-3 OK - -09-45-4 OK - -09-45-5 DIFF Partly fixed by rev 7617. Remaining diff is width of miter - extension in "Stroked Objects". Assign: Ray - -09-45-6 OK Fixed by r7123. - -09-45-7 OK - -09-46-1 OK Minor differences visually reviewed by RJJ - -09-46-2 OK - -09-47A-1 OK Matches Tek hardcopy output. RJJ - -09-47A-2 OK Matches Tek hardcopy output. Minor color differences. RJJ - -09-47A-3 OK Minor differences visually reviewed by RJJ - -09-47A-4 OK Matches Tek hardcopy output. RJJ - -09-47A-5 OK Matches Tek hardcopy output. RJJ - -09-47A-6 OK Matches Tek hardcopy output. RJJ - -09-47A-7 OK Matches Tek hardcopy output. RJJ - -09-47A-8 DIFF Resolution dependent: GS 'pattern' has double line joined, Tek - and CPSI do not although Tek and CPSI differ with pattern phase. - Assign: Ray - -09-47A-9 OK Fixed by rev 7169. - -09-47B-1 DIFF GS has different pattern phase. Tek and CPSI appear to be the same. - Assign: Ray - -09-47B-10 DIFF Test01 : aok - CPSI problem. The tensor patch has corner colors like this : - 00 55 - ff aa - Thus it must have a horizontal line of a constant color 80 - near the middle. The line is observable with GS and it is not with CPSI. - Analyzed by Igor. - - - Test09 - a color mapping problem. - Analyzed by Igor. - CIEBasedDEF colors are given with a sampled - (2 args, 2 results) function like this : - 000000 ff0000 - 00ff00 ffffff - With GS the brightness of magenta is asame as cyan. - CPSI paints a lighter magenta. - I guess something is wrong with WhitePoint in GS, - because an assimmetry red|blue must come from it. - The assymmetry is observing with CPSI and not with GS. - Assign to Tim - - - Test10: AOK - Match when using common CRD. - - - Test11: AOK - Match when using common CRD. - -09-47B-11 DIFF Test02, Test03 : aok. Same as 09-47B-10 Test11. - - - Test04: aok - Analyzed by Igor. - Likely CPSI problem. - The test is buggy - insufficient data for function. - It needs 16 samples, but 12 are only provided. - GS adds zeros at end. - 000000ff 000000ff - 00ffffff 00000000 - Thus the right end is Magenta+Yellow+Black = - (1-green + 1-blue)*(1-black) = - (1 + red)*(1-black). - It is observing with GS. - CPSI likely due to occasional data added at stream end. - See also Test11. - - - Test05: AOK - Analyzed by Igor. - A bad color CMYK=[1 1 1 1] in the test. - GPSI and GS differently convert [v v v v] CMYK colors to RGB. - Matches fine in 7736 with CPSI_mode = true. - Tim - - - Test06: AOK - Analyzed by Igor. - A bad color CMYK=[0.7 0.7 0.7 0.7] in the test. - GPSI and GS differently convert [v v v v] CMYK colors to RGB. - Matches fine in 7736 with CPSI_mode = true. - Tim - - - Test11: AOK - This is the same problem as Test04. Bug in test. - Insufficient data for function. - /CIEBasedDEFG as /DeviceCMYK in Test04 needs 16 samples, - and only 12 are provided. - Tim - - - Test12: - CIEBasedDEFG shading does not match CPSI. - Assign to Igor - -09-47B-12 AOK GS has wrong color Test06 GS not smooth Test07, Test08. - NOTE: Tek gets rangecheck error on Test03 Test10, CPSI and GS do not. - . - According to my reading of the spec, test6 should rangecheck, - but CPSI returns garbage data instead. r7130 improves match to - Tek output, but ultimately rendering of this page will be - device dependent, hence aok. - Raph - -09-47B-2 DIFF GS has different pattern phase. Tek and CPSI appear to be the same. - Assign: Ray - -09-47B-3 DIFF GS has different pattern phase. Tek and CPSI appear to be the same. - Assign: Ray - -09-47B-4 OK - -09-47B-5 OK Minor color difference, reviewed visually. RJJ - -09-47B-6 OK Fixed by rev 7169. - -09-47B-7 AOK Test01, Test02 : - Briefly analyzed by Igor. - Resolved by using common CRD. Tim - - - Test10: aok - CPSI problem : a non-monotonic color space is rendered as monotonic. - -09-47B-8 AOK Test01, Test02, Test03, Test05, Test08, Test09, Test10 : aok - Analized by Igor. - CPSI problem : a non-monotonic color is rendered as monotonic. - - - Test04, Test11: aok - Analized by Igor. - CPSI problem same as 09-47B-10 Test01. - -09-47B-9 AOK Test03, Test04, test05, Test06, Test07, Test10, Test11: aok - Analized by Igor. - CPSI problem : a non-monotonic color is rendered as monotonic. - - - Test08 : aok - Analized by Igor. - CPSI has a worse smoothness. - - - Test12 : aok - Analized by Igor. - CPSI problem same as 09-47B-10 Test01. - -09-47C-1 OK Fixed by rev 7221. - -09-47C-2 DIFF Rev. 7740 adds 'null' to the message. - Adobe shows: 'F --show-- rangecheck null' - At 144 dpi GS shows 'F --.type1execchar-- rangecheck null'. - At 72 dpi GS shows the same message as Adobe. assign: Peter - -09-47D-1 OK Fixed by rev 7169. - -09-47D-2 OK Fixed by rev. 7149. - -09-47D-3 OK Fixed by rev 7169. - -09-47D-4 OK Fixed by rev 7169. - -09-47D-5 OK Fixed by rev 7169. - -09-47D-6 OK Fixed by rev. 7149. - -09-47E-1 OK Fixed by rev 7169. - -09-47E-2 OK Fixed by rev 7149. - -09-47E-3 OK Fixed by rev 7169. - -09-47F-1 OK Fixed by rev 7169. - -09-47G-1 AOK Test06: ok. - rev. 7176 now properly sets errorinfo. - - - Test07: aok - Analyzed by Igor. - The test is buggy : insufficient stream data, - the effect does not correspond to the comment in the test. - Due to insufficient data GS adds zeros at end, - and the function becomes like this : - 000000 ff000000 ff00ff ffff0000 - 000000 00000000 000000 00000000 - The DeviceN maps it to DeviceRGB with dropping the last 4 components, - so we've got corner colors : - black magenta - black black - That's what we observe with GS. - There is a comment in gsdsrc.c ln 47 : - /* Access data from a string or a byte object. */ - /* Does check bounds, and returns 0 data oob. Spec calls for rangecheck, - but CPSI implementation silently gives (bogus) data. */ - Tek paints black magenta - black red - likely an occasional data at stream end. - - - Test10: aok - Analyzed by Igor. - A bug in the test : excessive stream data, - the effect does not correspond to the comment in the test. - The real effect is a linear sampled function like this : - Cyan: 00 00 - 00 ff - Magenta: 00 00 - 00 ff - Yellow: 00 00 - 00 ff - Black: 00 00 - 00 ff - Thus it paints bad CMYK colors [v v v v] for various v. - Same as 09-47B-11 Test05. - I believe that [1 1 1 1] is very black, right ? - Thus CPSI looks wrong. - GS looks close to Tek. - -09-47G-2 AOK Test01: ok - Fixed with rev 7199. - - - Test10: aok - Analyzed by Igor. - The linear sampled function is : - 000000 ff0000 - 00ff00 ffffff - The function's domain by the 2nd argument - is twice bigger than the shading domain. - Therefore the function linear is cropped to this : - 007700 ff7777 - 00ff00 ffffff - With CPSI it looks like this (wrong) : - 000000 ff0000 - 00ff00 ffff77 - With GS it looks like this (correct) : - 007700 FF7777 - 00ff00 777777 - CPSI appears wrong, GS appears correct. - - - Test11: aok - The function domain is cropped by both coordinates. - First convert to 3x3 : - 000000 770000 ff0000 - 007700 777733 ff7777 - 00ff00 77ff77 ffffff - Then crop with the "positive" quadrant : - 777733 ff7777 - 77ff77 ffffff - It looks close to what GS paints. - CPSI paints something like this : - 770000 ff0000 - ffff77 7777ff - CPSI appears wrong, GS appears correct. - -09-47G-3 AOK Test01: aok - The function 000000 ff0000 black red - 00ff00 ffffff green white - It is truncated with BBox/Matrix = 0.909, 0.933 - So by theory we get: - 000000 e70000 - e60000 d1d1d1 - It looks so with GS. - Don't know why CPSI misses green. - - - Test02 : Same as 09-47G-2 Test11. - -09-47H-1 OK Fixed by rev 7149. - -09-47H-2 OK Fixed by rev 7149. - -09-47H-3 OK Partially fixed by rev. 7169, finished by rev. 7176. - -09-47H-4 OK Fixed by rev 7206 - -09-47I-1 OK Fixed by rev 7149. - -09-47I-2 OK Fixed by rev 7175. - -09-47I-3 OK Test01, Test02, Test03, Test04, Test05, Test06, Test07: ok - Fixed by rev 7175. - - - Test11: OK. Looks fine in rev 7718. Tim. - -09-47I-4 OK Fixed as of rev 7211. - -09-47I-5 OK Fixed by rev 7175. - -09-47I-6 OK Fixed by rev 7175. - -09-47I-7 OK Test02, Test03, Test04: ok Fixed by rev 7175. - Test11: ok Fixed with rev 7179. - -09-47I-8 OK Test02, Test04: ok Fixed with rev 7179. - - - Test07, Test11: ok Fixed by rev 7175. - - - Test06, Test08: ok Fixed with rev 7218. - - - - Test12: ok Fixed by rev 7175. - -09-47J-1 DIFF Graphic differences in Test01 (partly drawn) and Test12 - (green line across the shading). Assign: Igor - -09-47J-10 OK - -09-47J-2 OK - -09-47J-3 AOK Test01 CPSI misses an imagemask with a shading color. - -09-47J-4 OK - -09-47J-5 OK - -09-47J-6 OK - -09-47J-7 OK - -09-47J-8 AOK Test01 CPSI misses an imagemask with a shading color. - -09-47J-9 OK - -09-47K-1 AOK Test01 CPSI yields a rangecheck while rendering - an imagemask or a character with a shading color. - and misses the rest of graphics. - I don't see any legal reason for rangecheck. - -09-47K-2 OK - -09-47K-3 OK - -09-47K-4 OK - -09-47K-5 OK - -09-47K-6 OK - -09-47K-7 AOK Test01 CPSI yields a rangecheck while rendering - an imagemask or a character with a shading color. - I don't see any legal reason for rangecheck. - Graphics appearance matches CPSI visually. - -09-47K-8 OK - -09-47L-1 AOK Test01 CPSI misses the character and imagemask with - a shading color. - -09-47L-2 OK - -09-47L-3 OK - -09-47L-4 OK - -09-47L-5 DIFF Test01 CPSI misses the character and imagemask with - a shading color. - Test07, Test08 -- GS missing 'wedges' in center region - of shading. - -09-47M-1 AOK Test01: The corner colors are : black red - green white - GS paints entire shading. - CPSI misses for imagemask and character. AD7 paints character, - but misses imagemask. - Analyzed by Igor. - -09-47M-2 OK Fixed by rev 7149. - -09-47M-3 OK Fixed by rev 7169. - -09-47M-4 AOK Test01 : ok, similar to 09-47M-1. (CPSI misses imagemask and - character, AD7 misses imagemask). - - - Test04: ok - Fixed with rev 7210. - Note: AD7 gets "drawing error" on the PDF it creates from this - as it is drawing Test04. GS is able to display entire Page and - output matches GS rendering of 09-47M.PS. Bug in Acrobat 7 - Reader! - - - Test09: ok - Fixed with rev 7210. - - - Test10, Test11, Test12: ok - Fixed by rev 7206 - -09-47M-5 AOK GS has smoother shadings (CPSI has triangle 'glitches' - with self-intersectint tensor: Test05, 06 - Test10-12). NOTE: Tek shapes and colors differ greatly. - -09-47N-1 DIFF A different flattening. Assign: Ray - -09-47N-2 OK Fixed by r7123. - -09-47N-3 AOK Really minor phase difference in pattern. RJJ - -09-48-1 OK Fixed in rev. 7138 - Alex - -09-48-2 OK Fixed by rev 7617. - -09-48-3 OK Fixed by r7123. - -09-48-4 OK - -09-49A-1 OK - -09-49B-1 OK - -09-49B-2 AOK Wrong value of AccurateScreens is fixed by rev. 7741. - CPSI-based PhotoPrint product ignores all attempts to change - the halftone and cannot be used as a reference. - GS is close to Tek Special Test B except for resolution - dependent numbers for ActualFrequency. Test C ActualFrequency is - also Device Dependent. - Alex - -09-49C-1 OK Matches Tek hardcopy and checksum. RJJ (CPSI differs because it - ignores setscreen). - -09-49D-1 OK Fixed by rev 7617. - -09-49D-2 OK Fixed by r7123. Color corrected by rev 7172. - -09-49D-3 OK Fixed by r7450 - -09-50-1 DIFF GS has different line spacing. CPSI and Tek agree. GS gets same - results for "false setstrokeadjust" "true setstrokeadjust". - Assign: Ray - -09-50-2 OK - -09-50-3 DIFF GS missing radial lines filling arcs. Tek and CPSI agree. May - be related to 09-24-2. Assign: Ray - -09-50-4 OK Fixed by r7123. - -09-50-5 OK - -09-51-1 OK Matches Tek hardcopy. RJJ (CPSI ignores settransfer). - -09-51-2 OK Fiexd by rev 7617. GS matches colors of Tek hardcopy, CPSI - shows MUCH different colors. - -09-51-3 OK Fixed by r7123. GS matches colors of Tek hardcopy, CPSI - shows MUCH different colors. - -09-51-4 OK Minor color difference (looks black to me). USE_ADOBE_CMYK_RGB issue - assign: Ray - -09-52-1 AOK Device Dependent: GS has default ProcessColorModel /DeviceRGB - CPSI has /DeviceN, Tek has /DeviceCMY (not a standard one??) - -09-52-2 OK Fixed by rev 7617. - -09-52-3 OK Fixed by r7123. - -09-52-4 OK Fixed by gs_cet.ps RJJ - -09-53-1 OK Fixed by r7155 - Raph - -09-53-2 OK Fixed by r7155 - Raph - -09-53-3 OK Minor differences visually reviewed by RJJ - -09-53-4 OK GS has different numbers (off by 1.0 or 2.0 out of ~120.0). Related - to cliprestore. - Fixed by r7155 - Raph - -09-53-5 OK Fixed by rev 7617. - -09-53-6 OK Fixed by r7123. Color corrected by rev 7172. - -09-53-7 OK - -09-54-1 AOK GS has > 1000 limit on clipsave. Tek and CPSI limit at 34. - Device Dependent. - -09-54-2 OK Fixed in r7155 - Raph - -09-54-3 OK Fixed in r7155 - Raph - -09-54-4 OK Fixed in r7155 - Raph - -09-54-5 OK Fixed in r7155 - Raph - -09-54-6 OK Fixed by rev 7617. - assign: Ray - -09-54-7 OK Fixed by r7123. Color corrected by rev 7172. - -09-54-8 OK Matches Tek hardcopy and CPSI. RJJ - -09-55-1 AOK Implementation dependent: GS allows small smoothness values, - Tek clamps lower value to 0.005, CPSI to 0.002. - -09-55-2 OK - -09-56-1 AOK Device Dependent: Tek and Adobe show '/findcolorrendering' - instead of '--findcolorrendering--' with errors. I've checked - in a fix for the setcolorrendering issue. /GenericImagesetter - and /AppleMonitor are CRD's provided by Adobe to OEM as - examples. They must be removed from the final product but - Scanvec-Amiable forgot. - - - The checksum depends on the order of resource enumeration, - which depends on the order of dictionary enumeration and - directory enumeration for external halftones. - -09-56-2 OK revisin 7234 (peter) - -09-56-3 OK Ghostscript matches the checksum for Tek360 version of the test. - PhotoPrint has extra '1' in GRAY33 that tests that whether the - change in colorspace affects CRD. Surprisingly, it does. - Tek scan and Distillier 5 have '1' in MEMO 03 and 04, i.e. - have different default CRD and a CRD returned by /Saturation - findcolorrendering. CRD selection is implementation dependent - and is normally left to OEM. - -09-57-1 AOK Fixed by rev 7169.; GS has a better smoothing. - -09-57-10 OK Fixed by rev 7169. - NOTE: Tek is MUCH different (wrong??) - -09-57-11 OK Fixed by rev 7169. - NOTE: Tek is all blank graphics (wrong??) - -09-57-12 OK Matches Tek hardcopy. RJJ (CPSI differs) - -09-57-13 AOK Test 09-12: With bad smoothness CPSI shadings are worse. - Analyzed by Igor. - -09-57-14 OK Fixed by rev 7617. - -09-57-15 OK Fixed by r7123. - -09-57-16 OK - -09-57-2 AOK Fixed by rev 7169.; GS has a better smoothing. - -09-57-3 AOK Fixed by rev 7169.; GS has a better smoothing. - -09-57-4 AOK Fixed by rev 7169.; GS has a better smoothing. - -09-57-5 AOK Fixed by rev 7169.; GS has a better smoothing. - -09-57-6 AOK Test04: With bad smoothness CPSI shadings are worse. - -09-57-7 OK - -09-57-8 OK Reviewed by RJJ. (something must have fixed this) - -09-57-9 OK Fixed by rev 7169. - -09-58-1 AOK Device Dependent: GS returns /none (4th line), Tek and CPSI return - /DefaultHalftone. GS matches Tek for some lines, CPSI for others. - -09-59-1 AOK Device Dependent: CPSI and Tek hardcopy differ. - -09-60-1 OK - -10-01-1 OK - -10-01-2 OK - -10-01-3 OK - -10-01-4 OK Minor differences in positions and character shapes - ADC - -10-01-5 OK Minor differences visually reviewed by RJJ - -10-01-6 AOK GS matches Tek hardcopy. CPSI differs in gradient in section - labeled 'Fountain_image' in the upper left.GS also - matches the appearance of of Distiller/Acrobat 7.0 - ADC - -10-01-7 OK Color corrected by rev 7172. - -10-02-1 OK - -10-02-2 OK - -10-02-3 OK - -10-02-4 OK - -10-02-5 OK - -10-02-6 OK Minor differences in positions and character shapes - ADC - -10-02-7 OK Minor differences visually reviewed by RJJ - -10-02-8 AOK Differences between CPSI and GS in gradient in section - labeled 'Fountain_image' in the upper right. However GS - matches the appearance of of Distiller/Acrobat 7.0. See - 10-01 page 6. - ADC - -10-02-9 OK - -10-03-1 AOK First section contains values dependent upon the initial CTM. - Different initial matrices for all three interpreters. - Notes: Acrobat and CPSI are rotated 180 degrees relative to - each other. Ghostscript changes the initial CTM based upon - the output device. - Distiller 7.0 reports: [ 8.333 0.0 0.0 -8.333 -2550.0 3301.0 ] - CPSI reports: [ -8.333 0.0 0.0 8.333 2550.0 -3301.0 ] - Ghostscript reports: [ 8.333 0.0 0.0 -8.333 0.0 6600.0 ] - -10-03-2 OK - -10-03-3 OK - -10-04-1 OK - -10-04-2 OK - -10-05-1 OK - -10-05-2 OK - -10-06-1 OK - -10-06-2 OK - -10-07-1 OK - -10-07-2 OK - -10-08-1 OK Minor differences in positions and character shapes - ADC - -10-08-2 OK Minor differences in positions and character shapes - ADC - -10-09-1 OK - -10-09-2 OK - -10-09-3 OK - -10-09-4 OK - -10-10-1 OK - -10-10-2 AOK Checksum 63395 does not match CPSI or Distiller/Acrobat 7.0. - The pages (and checksums) match Distiller 7.0 and CPSI except - for the 'much22' test. This test is specified by: - (/much22{ xy-t {0 -3 6 3 setbbox 3 0 1 0 360 arc 3 0 2 0 360 arc} ineofill not iff xyt }) - The operation {10 100 itransform} is run before and after - running the test. The results should match. However Distiller - 7.0 shows a -3.05176e-05 difference in the x value (307.2). - This appears to be a minor math problem in Distiller 7.0. CPSI - also shows an 'error' with this test. I do not have a copy of - CPSI to verify its values. Ghostscript produces matching values - (which is mathematically correct). - ADC - -10-11-1 OK - -10-11-2 OK - -10-12-1 OK - -10-12-2 OK - -10-12-3 OK Minor differences visually reviewed by RJJ - -10-12-4 AOK Differences between CPSI and GS in gradient in section - labeled 'Fountain_image' in the upper right. However GS - matches the appearance of of Distiller/Acrobat 7.0. See - 10-01 page 6. - ADC - -10-12-5 AOK Checksum 0 matches Distiller/Acrobat 7.0, CPSI 18736 matches - CET expected value. - ADC - -10-13-1 OK - -10-13-2 OK - -10-13-3 OK Minor differences in positions and character shapes - ADC - -10-13-4 OK Minor differences visually reviewed by RJJ - -10-13-5 AOK Differences between CPSI and GS in gradient in section - labeled 'Fountain_image' in the upper right. However GS - matches the appearance of of Distiller/Acrobat 7.0. See - 10-01 page 6. - ADC - -10-13-6 OK Color corrected by rev 7172. - -10-14-1 OK - -10-14-2 OK - -10-14-3 OK - -10-14-4 AOK Difference between CPSI and GS with several objects: - 1) The location of rectangles in items 13 and 14 in the - column labeled 'LOOK'. 2) The shape/locations of hooked - shape features in items 15, 16, and 18 in the same column. - 3) The length of a diagonal line in item 19 in the same - column. 4) The position of line and arc in items 22 and - 23 in the same column. 5) The position of diamond shaped - gradient at position 36 in the same column. 6) The position - of triangles at items 3 and 4 of a column labeled 'MEMO'. - 7) The positions of rectangles at items 22, 23, and 24, in - the column labeled 'CASH'. 8) The position of a larger - triangle at item 5 in the column labeled 'MUCH'. 9) The - position of trangles at items 8, 9, and 27 in the same column. - 10) The size of an 'angled' shaped objects at items 15 and - 30 in the same column. 11) The position of the triangle - at item 27 in the column labeled 'MORE'. 12) The location - of shaded squares in item 27 of the column labeled 'GRAY'. - 13) The location of rectangles in item 28 in the same column. - 14) The location of a trangle in item 32 in the same column. - For all of the above objects, the positions match between GS - and Distiller/Acrobat 7.0. - The one item that has some question, item 31 in the column - labeled 'GRAY' This is a triangle outline apparently drawn - with a pattern. All three intpreters differ. The GS output - looks like CPSI except that the pattern is mirrored about a - 45 degree diagonal. (Note: The pattern is only visible in - the lines that make up the lines of the triangle. Thus there - is very little information. The differences may be a minor - position shift.) Distiller/Acrobat differs from both. - ADC - -10-15-1 OK - -10-15-2 AOK The diffs in items 'much22' and 'much24' (user paths / insideness testing) - Analyzed by Igor. - This is a CPSI problem : the insideness testing operators - slightly disturb CTM.ty . - A simplified test case is placed to - peeves:/home/igor/pscet/mytests/10-15-2-Igor01.PS . - . - With this test CPSI prints : - GlobInterProc1=2467.17 - GIFBoundProc1=false - {749.8 1433.41 749.8 1433.41 setbbox 749.8 1433.41 moveto} - false - iff in : gif_assertion=true - iff out : gif_assertion=true - GifProcInstance=false - 1 - GlobInterProc2=2467.17 - GlobInterProc2=false - . - Note the value 2467.17 looks same due to rounding, - but the equality test fails (GlobInterProc2=false). - The effect is resolution dependent and the page size dependent. - -10-16-1 OK - -10-16-2 OK - -10-16-3 OK - -10-16-4 OK Minor differences visually reviewed by RJJ - -10-16-5 OK GS matches Tek hardcopy. CPSI differs in gradient in section - labeled 'Fountain_image' in the upper right. GS also - matches the appearance of of Distiller/Acrobat 7.0. See - 10-01 page 6. - ADC - -10-16-6 OK Minor differences in positions and character shapes - ADC - -11-01-1 AOK Matches Tek. CPSI slightly differs in few coordinates. - -11-01-2 OK - -11-01-3 OK - -11-01-4 OK - -11-01-5 OK - -11-01-6 AOK rev 7617 : look30, much34 look like a saw due to "strokepath stroke". - CPSI and GS rev 7617 generate individual contours for line joins, - which look like a quadrangle with a very acute corner. - Then it's a subject of miter limit, which depends on the angle, - which depends on the flattening factor of the original curve. - With CPSI look30 has a smaller number of peaks. - -11-02-1 AOK Same as 11-01-1 - -11-02-2 OK Minor differences visually reviewed by RJJ - -11-02-3 OK - -11-02-4 OK - -11-02-5 OK - -11-02-6 AOK Same as 11-01-6. - -11-03-1 OK Minor differences visually reviewed by RJJ - -11-03-2 OK - -11-03-3 OK Rev. 7171 works for me. - Alex - -11-03-4 OK Fixed in rev. 7171. - Alex - -11-03-5 OK Minor differences visually reviewed by RJJ - -11-03-6 OK Minor differences visually reviewed by RJJ - -11-03-7 OK Fixed as of rev 7618. - -11-04-1 OK Minor differences visually reviewed by RJJ - -11-04-2 OK - -11-04-3 OK Fixed iv rev. 7154. - Alex. - -11-04-4 OK - -11-04-5 OK Minor differences visually reviewed by RJJ - -11-04-6 OK Minor differences visually reviewed by RJJ - -11-04-7 OK Fixed as of rev 7618. - -11-05-1 OK Minor differences visually reviewed by RJJ - -11-05-2 OK Minor differences visually reviewed by RJJ - -11-05-3 OK Minor differences visually reviewed by RJJ - -11-05-4 OK - -11-05-5 OK Minor differences visually reviewed by RJJ - -11-05-6 OK fixed in r7228 - Raph - -11-05-7 AOK Same as 11-01-6. Color corrected by rev 7172. - -11-06-1 OK Minor differences visually reviewed by RJJ - -11-06-2 OK Fixed in r7155 - Raph - -11-06-3 OK Minor differences visually reviewed by RJJ - -11-06-4 OK Minor differences visually reviewed by RJJ - -11-06-5 AOK CPSI problem. - GS has extra line: MUCH 15, 30, 31. Tek and CPSI do not. - Analyzed by Igor. - The following test discovers a problem in CPSI : - . - 72 72 moveto 72 72 rlineto clip - 0 0 200 200 rectfill - showpage - 72 72 moveto 72 72 rlineto clip - 0 0 200 200 rectclip - clippath currentpoint - showpage - . - The test installs aclipping path from a single line. - The first page paints a line, so - the clipping is not empty. - The second page first installs same clipping, - and then applies rectclip over it. - The intersection isn't empty by theory, - but with CPSI it appears empty and - "clippath currentpoint" fails with nocurrentpoint. - -11-07-1 OK - -11-07-2 OK Minor differences visually reviewed by RJJ - -11-07-3 OK Minor differences visually reviewed by RJJ - -11-07-4 OK Minor differences visually reviewed by RJJ - -11-07-5 OK Fixed by rev 7617. - -11-08-1 OK Minor differences visually reviewed by RJJ - -11-08-2 OK Minor differences visually reviewed by RJJ - -11-08-3 OK Minor differences visually reviewed by RJJ - -11-08-4 OK Minor differences visually reviewed by RJJ - -11-08-5 OK Fixed as of rev. 7531. - -11-09-1 AOK a better stroke adjustment; not important. Analyzed by Igor. - -11-09-2 OK - -11-09-3 OK - -11-09-4 AOK linewidth different. - Analyzed by Igor. - GS paints a "thin line" whenever the line wdth is lesser than 1 pixel. - The decision is taken in gxstroke.c ln 453, 468, 482 - with the threshold half width smaller than half pixel. - Well I can set a smaller threshold for CPSI compatibility, - but I need CPSI to measure its constant. - -11-09-5 OK Minor differences visually reviewed by RJJ - -11-09-6 OK - -11-09-7 OK - -11-09-8 AOK look30, much34 : AOK same as 11-01-6. - - - more21: aok - CPSI appears ignoring the bad flattening precision. - May be related to 11-09-4 assign: Ray. - -11-10-1 AOK Test measures number of subdivisions with different values of - setflat. Differences are expected (resolution dependent). -Raph - -11-10-2 OK Minor differences visually reviewed by RJJ - -11-10-3 OK Minor differences visually reviewed by RJJ - -11-10-4 DIFF setflat problem maybe - curves smooth in cpsi assign: Raph. - We have very coarse flattenpath results. - Raph - -11-10-5 DIFF same as 11-10-4 assign: Raph. - Same as 11-10-4 - -11-10-6 OK Fixed as of rev 7618. - -11-11-1 OK Fixed with rev 7212. - -11-11-2 OK - -11-11-3 OK - -11-11-4 OK Minor differences visually reviewed by RJJ - -11-11-5 OK Minor differences visually reviewed by RJJ - -11-11-6 OK Fixed as of rev 7534. - -11-12-1 OK - -11-12-2 OK - -11-12-3 OK - -11-12-4 OK Minor differences visually reviewed by RJJ - -11-12-5 OK Minor differences visually reviewed by RJJ - -11-12-6 OK Minor differences visually reviewed by RJJ - -11-13-1 OK Minor differences visually reviewed by RJJ - -11-13-2 OK - -11-13-3 OK - -11-13-4 OK Works in rev. 7527. - -11-14-1 OK Fixed with rev 7213. - -11-14-2 OK - -11-14-3 OK Minor differences visually reviewed by RJJ - -11-14-4 OK Minor differences visually reviewed by RJJ - -11-14-5 OK fixed in r7228 - Raph - -11-14-6 OK Color corrected as of rev 7172. - -11-15-1 OK Fixed as of rev 7534. - -11-15-2 OK Minor differences visually reviewed by RJJ - -11-15-3 OK Minor differences visually reviewed by RJJ - -11-15-4 OK - -11-15-5 OK Minor differences visually reviewed by RJJ - -11-15-6 OK Minor differences visually reviewed by RJJ - -11-15-7 OK Minor differences visually reviewed by HAS - -11-16-1 OK Minor differences visually reviewed by HAS - -11-16-2 OK - -11-16-3 OK - -11-16-4 OK Minor differences visually reviewed by HAS - -11-16-5 OK - -11-16-6 OK - -11-16-7 OK - -11-16-8 AOK - -11-17-1 OK Fixed as of rev 7598. - -11-17-2 OK Fixed as of rev 7598. - -11-17-3 OK Minor differences visually reviewed by RJJ - -11-17-4 OK Minor differences visually reviewed by RJJ - -11-17-5 OK fixed in r7228 - Raph - -11-17-6 AOK GS has small square in upper right of border line, CPSI has - similar square in lower right. Tek has small square in lower - right. Device Dependent: Uses device coordinates, GS, Tek - and CPSI all have different default CTM. RJJ - -11-18-1 OK Fixed with rev 7212. - -11-18-2 OK - -11-18-3 OK - -11-18-4 OK Minor differences visually reviewed by RJJ - -11-18-5 OK Minor differences visually reviewed by RJJ - -11-18-6 AOK Adobe interpreters (CPSI, Tek, Distiller 5) have obvious - rendering problems, which are hard to simulate in GS. - 1. The long diagonal line is caused by "clippath 0 0 rlineto - stroke showpage". Different Adobe interpreters draw it - fron the center of the page to different corners. - 2. The line drawn by "10 0 rlineto" is not horizontal in - LOOK 30 and MUCH 34 cases. This bug can be demonstrated - by this short program "300 300 moveto 10 10 rlineto 8 8 - rlineto strokepath 10 0 rlineto stroke showpage". - Alex - -11-19-1 OK - -11-19-2 OK - -11-19-3 OK - -11-19-4 OK Minor differences visually reviewed by RJJ - -11-19-5 OK Minor differences visually reviewed by RJJ - -11-19-6 AOK cash21, look30 : ustrokepath ending point, Analyzed by Igor. - I believe it is CPSI problem. - I placed some tests to peeves:/home/igor/pscet/mytests/11-19-Igor01.zip . - The ZIP contains 2 PS files, which are made from 11-19.PS - with removing unrelated things and inserting a debug printing. - The 2 files differ in a small thing : wheter it access - currentpoint after ustrokepath, or not. - The rasters (included into the ZIP) appear to be different ! - The log files (included into the ZIP) tell us that no error happen, - because the currenpoint coordinates are successfully printed - (in the order Y X). - The position of the 2nd cross depends on the - currentpoint after ustrokepath, - but 'currentpoint' appears to cnahge it ! - I believe that CPSI actually didn't pass the "interference" test, - which 1-19-6 is designed for. - As we noticed from other 20 tests (unpublished), this behavior - appears pretty occasional, so we're unable to analyze it completely - and to reproduce it in Ghostscript. - Tek matches CPSI though - I can't know why. - Welcome anybody who can improve this analyzis. - -11-20-1 OK Minor differences visually reviewed by HAS - -11-20-2 OK Differences resolved as of rev 7531. - -11-20-3 OK Minor differences visually reviewed by RJJ - -11-20-4 OK - -11-20-5 DIFF Analyzed by Igor. - I believe it is CPSI problem. - A simplified test is stored into peeves/home/igor/pscet/mytests/11-20-5-Igor01.ps . - It prints the pathbbox before and after "3 3 rlineto", - as well as the current point before and after it : - bbb0 - 711.0 - 289.037 - 691.0 - 80.3225 - xxx0 - 691.0 - 85.535 - bbb1 - 711.0 - 289.037 - 691.0 - 39.5 - xxx1 - 694.0 - 88.535 - 11-20 GSTATE = 31293 Graphic 0 ms - . - Note: pathbbox and currentpoint are printed in the reverse order. - The starting and the ending point of the line appear - within the initial pathbbox. - In same time the lower X of pathbbox changes from 80.3225 to 39.5 - without a visible reason. With GS it doesn't change. - Note: my copy of CPSI probably is some older, - but it renders same 11-20-5.ppm as one on peeves. - Passing to Ray for further processing. - assign: Ray. - -11-20-6 DIFF In special test B, Adobe has rangechecks, we don't. In - special test A, we have one rangecheck they don't. - The test is about interaction of setbbox with save, - gsave and other operators. - assign Raph - -11-20-7 OK - -11-20-8 OK Minor differences visually reviewed by RJJ - -11-20-9 DIFF '4's and '1's added in gs output. - The problem (at least partly) is caused by a small bounding box - set by setbbox operator that cannot accomodate long strings of text. - Adobe appears to extend path bounding box on demand instead of - enforcingwhen the limits when the current point comes from a - different gstate, for instance: - "0 0 moveto gsave 0 0 5 5 setbbox 10 10 lineto stroke showpage" - assign Alex - -11-21-1 OK Fixed as of rev 7598. - -11-21-10 AOK Differences in look20, look30, look33 are caused by CPSI problem : - rlineto, rcurveto count wrong coordinates after strokepath. - It looks as the starting point for relative coordinate is not equal to - the current point. CPSI paints a self-intersecting curve with - "9 0 9 -9 0 -9 rcurveto stroke", which must not self-intersect. - A simplified test is placed to - peeves:/home/igor/pscet/mytests/11-21-10-Igor01.ps - -11-21-2 OK Minor differences visually reviewed by RJJ - -11-21-3 OK Fixed by rev 7617. - -11-21-4 DIFF Analyzed by Igor. - There are several stroking problems. - 1. linewidth - same as 11-09-4. - 2. setflat - same as 09-09-1. - 3. CPSI doesn't roll a dash pattern at some corners. - An example is at the lower right corner of the page. - The dash at one corner looks longer than the distance to the corner. - IMO it's another CPSI bug. - Passing to Ray do decide what to to with it. - assign: Ray. - -11-21-5 OK Minor differences visually reviewed by HAS - -11-21-6 AOK Resolution dependent: GS gives pathbox exact (not enlarged - slightly). Tek and CPSI differ. - - - curve saw : AOK - same as 11-01-6. - -11-21-7 OK Fixed by rev. 7701 - Alex - -11-21-8 AOK Device Dependent / Resolution Dependent. CPSI ignores setflat - Tek and CPSI differ. - -11-21-9 AOK flattness differ. Tek and CPSI differ. - -11-22-1 OK - -11-22-2 OK Minor differences visually reviewed by RJJ - -11-22-3 AOK CPSI is wrong with the invalid test "User path must start with absolute point". - -11-22-4 OK - -11-22-5 DIFF GS has different number. Although this is resolution dependent, - the test comment indicates what should happen. Tek has 0.12 - values, CPSI has 0.06 (approx.). Assign: alex - -11-22-6 OK shape has a small 'point' with CPSI, Ghostscript matches Tek - hardcopy [2nd row down, right side, upper curve.] - -11-22-7 OK fixed in r7228 - Raph - -11-22-8 OK Fixed as of rev 7618. - -11-23-1 AOK GS (apparently) does not implement upath caching. Tek and CPSI - do, but differ. Device Dependent (as comment says). - -11-23-2 OK Minor differences visually reviewed by RJJ - -11-23-3 OK ucache typecheck error in gs not seen in cpsi. - fixed in r7229 - Raph - -11-23-4 OK - -11-24-1 OK - -11-24-2 OK - -11-24-3 AOK user path : - CPSI doesn't follow PLRM page 199 about user paths : - "the first operator after setbbox must be an absolute positioning operator - (moveto, arc, or arcn)." - "All coordinates specified as operands must fall within the bounds - specified by setbbox". - When an user path starts with rmoveto, CPSI looks using current point - from the graphic state when it is set, and probably the setbbox lower coordinates - when current point is not set. However arc, arcn in the user path - do not paint a line from the graphic state current point. - Also painting outside setbbox somethimes throws error, sometimes not - - we could not figure out what does it depend on. - Due to all that CPSI's algorithm isn't clear and we're unable to reproduce it. - Will follow PLRM instead. - -11-24-4 OK - -11-24-5 OK - -11-24-6 OK - -11-24-7 OK Minor differences visually reviewed by RJJ - -11-24-8 OK - -11-25-1 OK - -11-25-2 OK - -11-25-3 AOK user paths : same as 11-24-3. - -11-25-4 OK - -11-25-5 OK - -11-25-6 OK - -11-25-7 OK Minor differences visually reviewed by RJJ - -11-25-8 OK - -11-26A-1 OK Minor differences visually reviewed by HAS - -11-26A-2 OK Minor differences visually reviewed by RJJ - -11-26A-3 OK Fixed as of rev 7598. - -11-26B-1 OK Minor differences visually reviewed by RJJ - -11-26B-2 DIFF precision discrepancies assign Alex - -11-26C-1 OK Minor differences visually reviewed by RJJ - -11-26C-2 OK Minor differences visually reviewed by RJJ - -11-26C-3 OK Minor differences visually reviewed by RJJ - -11-26D-1 OK Minor differences visually reviewed by RJJ - -11-26D-2 OK fixed in rev 7228 - Raph - -11-26D-3 OK Minor differences visually reviewed by HAS - -11-27-1 OK Minor differences visually reviewed by RJJ - -11-27-2 OK - -11-27-3 AOK user paths : same as 11-24-3. - -11-27-4 OK - -11-27-5 OK - -11-27-6 OK - -11-27-7 OK Minor differences visually reviewed by RJJ - -11-27-8 OK - -11-28-1 DIFF GS has much different stroke pattern in circles/wedges. Tek - and CPSI agree. May be setflat issue. Assign: Ray - -11-28-10 AOK same as 11-21-8. - -11-28-11 AOK same as 11-21-9. - -11-28-12 AOK same as 11-21-10. - -11-28-2 OK Fixed by rev 7617. - -11-28-3 AOK curve saw : AOK - same as 11-01-6. - -11-28-4 AOK CPSI stroking problem. CPSI and Tek differ. - -11-28-5 OK Fixed as of r7231. - -11-28-6 OK Minor differences visually reviewed by RJJ - -11-28-7 OK Minor differences visually reviewed by HAS - -11-28-8 DIFF same as 11-21-4 assign: Ray. - -11-28-9 OK Fixed by rev. 7701 - Alex - -12-01-1 OK Minor text outline differences - ADC - -12-01-2 OK Minor differences visually reviewed by RJJ - -12-01-3 OK Minor differences versus CPSI- ADC. PDF produced by Distiller 7.0 - shows teal colored circles. (GS and CPSI render sea foam green.) - -12-01-4 OK Minor differences visually reviewed by RJJ. - -12-01-5 DIFF Magenta in pattern in lower right corner of GS output. Not seen in - CPSI output. Strange result in Distiller 7.0 output. Acrobat 7.0 - reports incorrect number of values for setcolor operator. Page is - blank. - See also 18-02G-1. - Partial analysis from Jan (11/29/2006) - 1. An uncolored pattern is created, and used to draw the region on - the left. The pattern consists of a 9 unit x 9 unit tile, in the - center of which is a 7 unit x 7 unit colored square. The pattern - receives its color at the time the setpattern operator is invoked. - For this test, that color is black. - -- - 2. Next, a colored pattern is created, and used to draw the figure - on the right. This pattern also consists of a 9 unit x 9 unit tile, - whose PaintProc operates as follows: - - create a path consisting of a 5 unit x 5 unit square centered - in the 9 unit x 9 unit tile - - save graphic state - - set an approximately magenta color and fill the square - - restore the graphic state - - outline the same square with an approximately 4 unit wide line; - this line obscures all but a 1/2 unit x 1/2 unit square of the - magenta region - The key step is the last one, because the PaintProc does not set a - color for drawing the line. In this case it inherits the color - from the graphic state in effect when the makepattern operator was - invoked, which is the uncolored pattern created in Step (1). - -- - 3. Ghostscript renders the uncolored pattern into a gx_color_tile - structure when drawing the left region, and caches that strcuture. - When the second region is to be rendered, another gx_color_tile - is created, and the cached tile of the uncolored pattern is used - (in part) to render this new tile. The caching accumulator - device is used for this purpose. - -- - 4. The problem arises because the cached gx_color_tile for the - uncolored pattern has its phase information set for the original - device, not the accumulator device being used to create the tile - for the colored pattern. - -- - As we noted earlier, Ghostscript renders patterns to - gx_color_tile structures of minimum size. Such a mechanism - cannot handle the general case in which one pattern makes use of - another pattern. Either the tile size must be increased to the - least common multiple of the patterns' step sizes, or some more - elaborate compositing technique must be used for final rendering. - -- - However, in this case both patterns have the same step sizes (and - the same tile size), so Ghostscript should be able to handle the - situation correctly. We thought the problem was that the - uncolored pattern was already cached, and so we modified the code - to discard cached patterns just before executing a pattern - PaintProc. That resolves the phase issue, but the "inner" - pattern (the uncolored pattern in this case) is rendered using - the wrong transformation matrix. We haven't yet had time to go - back and determine why this is happening. - Assign: Tim - -12-01-6 OK Minor differences in positions and character shapes - ADC - -12-02-1 OK Minor differences in positions and character shapes - ADC - -12-02-10 OK Minor differences in positions and character shapes - ADC - -12-02-11 OK Minor differences visually reviewed by RJJ - -12-02-12 OK Minor differences, colors more vibrant in shadings in GS. - -12-02-13 OK Minor differences in positions and character shapes - ADC - -12-02-14 OK Corrected by 7152 and 7162. ADC - -12-02-15 OK Minor differences in positions and character shapes - ADC - -12-02-16 OK Minor differences in positions and character shapes - ADC - -12-02-17 OK Minor differences in positions and character shapes - ADC - -12-02-18 AOK Squares in the top row are darker in GS vs CPSI. - This is exactly the same issue as 12-07B-10. After embedding - CPSI's default CRD into the job, the output matches. TIM - -12-02-19 OK Minor differences in positions and character shapes - ADC - -12-02-2 OK Minor differences in positions and character shapes - ADC - -12-02-3 OK Minor differences in positions and character shapes - ADC - -12-02-4 OK Minor differences in positions and character shapes - ADC - -12-02-5 OK Minor differences in positions and character shapes - ADC - -12-02-6 OK Corrected by 7152 and 7162. ADC - -12-02-7 OK Minor differences in positions and character shapes - ADC - -12-02-8 OK Minor differences in positions and character shapes - ADC - -12-02-9 OK Minor differences in positions and character shapes - ADC - -12-03-1 OK Corrected by 7152 and 7162. ADC - -12-03-2 OK Minor differences visually reviewed by RJJ - -12-03-3 OK Minor differences in positions and character shapes - ADC - -12-03-4 OK Minor differences visually reviewed by RJJ - -12-03-5 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign Tim - -12-03-6 OK Minor differences in positions and character shapes - ADC - -12-04-1 OK Verified by ADC - -12-04-2 OK Corrected by 7152 and 7162. ADC - -12-04-3 OK Minor differences visually reviewed by RJJ - -12-04-4 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign: Tim - -12-04-5 AOK GS has extra center line on symbols: LOOK 3, 12 , MUCH 9, MORE 19 - Analyzed by Igor : - I believe it is a CPSI problem. - eofill is applied to two overlapping horizontal lines. - In most cases CPSI paints them, and sometimes doesn't. - Tek paints always. - GS matches Tek. - -12-05-1 OK Minor differences in positions and character shapes - ADC - -12-05-2 OK - -12-05-3 AOK Page is gray in GS. White in CPSI. - This "{.75 mul} settransfer erasepage showpage" gives - a gray page in GS. - -- - I ran this job through Acrobat Distiller 5.0 as well as Apple's - Preview, they match the GS output. The Red Book states that - erasepage is influenced "if an atypical transfer function has - been defined"... Since the transfer function is {.75 mul} a gray - value of R=191,G=191,B=191 should be expected from all that I - can see and reproduce here. I noticed it is noted several times - that "CPSI ignores settransfer". I believe this is another case - where whatever version of CPSI is used to generated these - PPM's, settransfer looks to be ignored. TIM - -12-06-1 OK Minor differences in positions and character shapes - ADC - -12-06-2 OK Corrected by 7152 and 7162. ADC - -12-06-3 OK - -12-06-4 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign: Tim - -12-06-5 OK Minor differences in positions and character shapes - ADC - -12-07A-1 DIFF? Different blurring in squares in 7th column compared to CPSI. - GS blurring matches appearance of Distiller/Acrobat 7.0 - assign: Tim - -12-07A-10 OK Minor differences visually reviewed by RJJ - -12-07A-11 OK Minor differences visually reviewed by RJJ - -12-07A-12 OK Adobe acceptts images in the pattern color space. - Since rev. 7597 we do the same in the compatibility mode. - Alex - -12-07A-13 OK Minor differences in positions and character shapes - ADC - -12-07A-14 OK Minor differences in positions and character shapes - ADC - -12-07A-15 OK Minor differences in positions and character shapes - ADC - -12-07A-2 OK Minor differences in positions and character shapes - ADC - -12-07A-3 DIFF Squares are blurred in GS. No blurring in CPSI. Distiller/Acrobat - 7.0 shows blurring similar to GS. - assign: Tim - -12-07A-4 OK Minor differences in positions and character shapes - ADC - -12-07A-5 DIFF Page consists of blurred squares. GS position shifted down slight - at the top of the page vs CPSI and Distiller/Acrobat 7.0. - ADC - assign: Tim - -12-07A-6 OK Minor differences in positions and character shapes - ADC - -12-07A-7 OK Minor differences in positions and character shapes - ADC - -12-07A-8 OK Minor differences visually reviewed by RJJ - -12-07A-9 OK Minor differences visually reviewed by RJJ - -12-07B-1 OK Minor differences in positions and character shapes - ADC - -12-07B-10 AOK Some grays in the top row are lighter in GS versus CPSI - (after 7152). - ADC - This is exactly the same issue as 12-02-18. After embedding - CPSI's default CRD into the job, the gray rectangles in the top - row match. TIM - -12-07B-11 DIFF Some grays in the top row are lighter in GS versus CPSI - (after 7152). - ADC Assign Tim - -12-07B-12 DIFF Blurred images render a slight position shift relative to CPSI and - Distiller/Acrobat 7.0 - ADC assign: Tim - -12-07B-13 DIFF Several differences. Color squares are missing in GS. The - Distiller/Acrobat 7.0 shows these squares blurred. They are not - in both GS and CPSI. - ADC assign: Tim - -12-07B-14 DIFF Several differences. Color squares are missing in GS. The - Distiller/Acrobat 7.0 shows these squares blurred. They are not - in both GS and CPSI. - ADC assign: Tim - -12-07B-15 DIFF Several differences. Dark squares are missing in GS. There are - dfferences in the blurring between Distiller/Acrobat 7.0 vs GS - and CPSI. - ADC assign: Tim - -12-07B-2 OK Minor differences in positions and character shapes - ADC - -12-07B-3 OK Minor differences in positions and character shapes - ADC - -12-07B-4 OK Minor differences in positions and character shapes - ADC - -12-07B-5 OK Minor differences in positions and character shapes. Some - minor differences in shades of gray. - ADC - -12-07B-6 OK Minor differences in positions and character shapes. Some - minor differences in shades of gray. - ADC - -12-07B-7 OK Minor differences in positions and character shapes - ADC - -12-07B-8 OK Minor differences in positions and character shapes - ADC - -12-07B-9 OK Minor differences in positions and character shapes. Some - minor differences in shades of gray. - ADC - -12-07C-1 OK Minor differences in positions and character shapes - ADC - -12-07C-10 DIFF White and black rectangles missing in GS. Differences between - CPSi and Distiller/Acrobat 7.0 - ADC assign Tim - -12-07C-11 DIFF White and black rectangles missing in GS. Differences between - CPSi and Distiller/Acrobat 7.0 - ADC assign Tim - -12-07C-12 DIFF White and black rectangles missing in GS. Differences between - CPSi and Distiller/Acrobat 7.0 - ADC assign Tim - -12-07C-13 DIFF White, black, and cyan rectangles missing in GS. Differences - between CPSi and Distiller/Acrobat 7.0 - ADC assign Tim - -12-07C-14 OK Minor differences in positions and character shapes - ADC - -12-07C-15 OK - -12-07C-16 OK - -12-07C-17 OK - -12-07C-2 OK Minor differences in positions and character shapes - ADC - -12-07C-3 OK Minor differences in positions and character shapes - ADC - -12-07C-4 OK Minor differences visually reviewed by RJJ - -12-07C-5 OK Minor differences visually reviewed by RJJ - -12-07C-6 OK Minor differences in positions and character shapes - ADC - -12-07C-7 OK GS matches Tek -- no thin vertical lines. - -12-07C-8 DIFF GS missing leftmost vertical column of shaded data in the - test block at the lower right of the page - ADC. assign Tim - -12-07C-9 OK Color corrected by rev 7172. Something fixed the error message. - -12-07D-1 OK Minor differences in positions and character shapes - ADC - -12-07D-2 OK Minor differences in positions and character shapes - ADC - -12-07D-3 OK Minor differences visually reviewed by RJJ - -12-08A-1 DIFF Differences in the second and third test pattern in the rightmost - column. GS pattern matches Distiller/Acrobat. CPSI is different. - Adobe shows these a blurred. Both CPSI and GS are crisp. - ADC - assign Tim - -12-08A-2 OK Minor differences in positions and character shapes - ADC - -12-08A-3 DIFF Different pattern between GS and CPSI. Distiller/Acrobat shows - the same pattern as GS. Adobe shows the image blurred. Both - CPSI and GS shows a crisp image. (The page says interpolate - true in the upper left corner.) - ADC - assign Tim - -12-08A-4 OK Color corrected by rev 7172. - -12-08A-5 AOK Minor differences in positions and character shapes. - -12-08A-6 AOK Minor differences in positions and character shapes. - -12-08A-7 OK Color corrected by rev 7172. - -12-08A-8 OK Color corrected by rev 7172. - -12-08B-1 OK Minor differences in positions and character shapes - ADC - -12-08B-2 OK Accept multiple data sources in imagemask by rev. 7181. - -12-08B-3 OK Minor differences in positions and character shapes - ADC - -12-08C-1 OK Minor differences in positions and character shapes - ADC - -12-08C-2 OK Color corrected by rev 7172. - -12-08C-3 OK Minor differences in positions and character shapes - ADC - -12-08C-4 OK Minor differences in positions and character shapes - ADC - Color corrected by rev 7172. - -12-08D-1 OK Minor differences visually reviewed by RJJ - -12-08D-2 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign: Tim - -12-08D-3 OK Minor differences in positions and character shapes - ADC - -12-09-1 OK Minor differences in positions and character shapes - ADC - -12-09-2 OK Minor differences in positions and character shapes - ADC - -12-09-3 OK Minor differences in positions and character shapes - ADC - -12-09-4 OK Minor differences in positions and character shapes - ADC - -12-10-1 OK Minor differences in positions and character shapes - ADC - -12-10-2 OK Color corrected by rev 7172. - -12-10-3 OK Minor differences visually reviewed by RJJ - -12-10-4 OK Color corrected by rev 7172. - -12-10-5 OK Minor differences visually reviewed by RJJ - -12-10-6 OK Minor differences in positions and character shapes - ADC - -12-10-7 OK Minor differences in positions and character shapes - ADC - -12-10-8 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign: Tim - -12-10-9 OK Minor differences in positions and character shapes - ADC - -12-11-1 OK Minor differences in positions and character shapes - ADC - -12-11-2 OK Color corrected by rev 7172. - -12-11-3 OK Minor differences in positions and character shapes - ADC - -12-11-4 OK reviewed by RJJ. - -12-11-5 OK Minor differences in positions and character shapes - ADC - -12-11-6 OK Minor differences visually reviewed by RJJ - -12-11-7 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign: Tim - -12-11-8 OK Minor differences in positions and character shapes - ADC - -12-12-1 OK Minor differences in positions and character shapes - ADC - -12-12-10 OK - -12-12-2 OK Minor differences in positions and character shapes - ADC - -12-12-3 OK Minor differences in positions and character shapes - ADC - -12-12-4 OK Color corrected by rev 7172. - -12-12-5 OK Color corrected by rev 7172. - -12-12-6 OK Minor differences in positions and character shapes - ADC - -12-12-7 OK Color corrected by rev 7172. - -12-12-8 OK - -12-12-9 DIFF A pattern phase difference. assign: Tim - -12-13-1 OK Minor differences in positions and character shapes - ADC - -12-13-2 OK - -12-13-3 OK Minor differences visually reviewed by RJJ - -12-13-4 DIFF Magenta in pattern at lower right in GS. Not present in CPSI. - See 12-01-5. Assign: Tim - -12-13-5 OK Works for me in rev. 7579. There's no differences around 30 - and 31 in left column. The checksum matches too. - Alex. - -12-14A-1 OK Test03: ok - fixed. - rangecheck error is fixed - Alex. - -12-14A-10 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14A-11 DIFF Analyzed by Igor. - Test03: diff - same as 09-47B-11 Test05. Assign: Tim - - - Test04: aok. Similar to 09-47B-10 test11. - - - Test05, Test12: aok - A bug in the test : insufficient data. - The stream interpretes like this : - 000000ff 000000ff black black - 00ffffff 00000000 black-red white - CPSI renders : - black green - black black -- looks wrong. - GS renders : - black red white - black black black --- looks correct. - - - Test08, Test09: ? - same as 09-47B-11 Test05. Assign: Tim - Please pay attention to the vertical diagonal of the rhombus. - With CPSI it looks as a linear gradient, and does not with GS. - Looks that CMYK colors [v v v v] differently convert to RGB. - Not sure who is wrong, but CPSI looks more pleasant. - -12-14A-12 DIFF Test03, 04, 10,11 : - same as 09-47B-11 Test05. Assign: Tim - - - Test07: aok - same as 12-14A-11 Test05. - -12-14A-13 DIFF Test02:aok - same as 12-14A-11 Test05. - - - Test03: aok. same as 09-47B-10 Test11. - - - Test04: - GS problem with non-contigous function. - A fix is possible but isn't simple. - A suggestion was posted to 'teco' on November 8 - and then dismissed. Now it arises anew. - . - First we need gs_function_evaluate to return a new bit. - which tells that the function has a discontinuty at - the point. Fortunately poly-argument PS finctions are - always contigous (otherwise the topology of discontinuty - would be a hell). - . - There are 20 calls to patch_interpolate_color, - which deal with it. It must return a bit, - which tells whether the function - isn't contiguous at the point. - If so, it must be called at second - time for computing another limit to this point. - . - The change should look like this : - . - + typedef enum {left, right} function_limit_direction; - . - { - - patch_color_t c; - + patch_color_t *C; - + function_limit_direction discontinuty; - - patch_interpolate_color(&c, c0, c1, pfs, 0.5); - + discontinuty = patch_interpolate_color(&c, c0, c1, pfs, 0.5, left); - + if (discontinuty) - + patch_interpolate_color(&C, c0, c1, pfs, 0.5, right); - + else - + C = &c; - // Then a half of occurances 'c' to be replaced with 'C'. - } - . - Assign: igor. - - - Test05, 06, 07, 08, 12 : same as 09-47B-11 Test05. Assign: Tim - - - Test09: aok - same as 09-47B-11 Test04. - Likely CPSI problem. - The test is buggy - insufficient data for function. - The data are interpreter like this : - 000000ff000000 ff00ffffffxxxx - xxxxxxxxxxxxxx xxxxxxxxxxxxxx - where x is an insufficient data. GS pads it with zeros, - CPSI is indeterministic. - After tintTransform we get CMYK colors : - 000000ff ff00ffff - xxxxxxxx xxxxxxxx - GS should paint : black black*green - white white - It's what we observe. - CPSI appears wrong. - -12-14A-14 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14A-2 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14A-3 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14A-4 OK GS error reports are changed to match CPSI. - Alex - -12-14A-5 AOK GS error reports are changed to match CPSI. - Alex - - - Test07, 10, 11, 12 : aok - CPSI problem : a non-monotonic color space is rendered as monotonic. - Same as 09-47B-7 Test10. - -12-14A-6 OK Minor differences in positions and character shapes and minor - differences in shading gradients. GS gradients are smoother - in tests 3 and 4. - ADC - -12-14A-7 AOK Test01, 02, 03, 04, 07, 08, 09, 10 : aok - CPSI problem : a non-monotonic color space is rendered as monotonic. - Same as 09-47B-7 Test10. - -12-14A-8 AOK CPSI reports 7 typechecks in shfill. GS reports none. There - are 7 gradients missing in test 6 to 12 in CPSI. - ADC - - - Analyzed by Igor : - CPSI misses the gradients due to the typecheck mentioned above. - PLRM doesn't allow packedarray as 'names' element of the color space. - GS appears tolerant to it. - IMO it should be aok. - -12-14A-9 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14B-1 OK All test report errors now match CPSI and the test. - Alex - -12-14C-1 OK Fixed - Alex. - -12-14D-1 OK Fixed in rev. 7209. - Alex - -12-14E-1 OK All test report errors now match CPSI and the test. - Alex - -12-14F-1 OK All test report errors now match CPSI and the test. - Alex - -12-14G-1 OK All test report errors now match CPSI and the test. - Alex - -12-14H-1 OK Minor differences visually reviewed by RJJ - -12-14H-2 OK Minor differences in positions and character shapes - ADC - -12-14H-3 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14I-1 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14I-2 OK Minor differences in positions and character shapes - ADC - -12-14I-3 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14I-4 OK Minor differences visually reviewed by RJJ - -12-14J-1 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14J-2 OK Minor differences in positions and character shapes - ADC - -12-14J-3 OK Minor differences in positions and character shapes and minor - differences in shading gradients. - ADC - -12-14K-1 AOK Test04: aok - CPSI is wrong, GS is correct. - The test is buggy : it contains a wrong comment about colors - and excessive data for the function. - There is nothing special about diagonals in the function, - so CPSI paints them inaccurately. - - - Test06: aok - The test is buggy : it contains a wrong comment about colors - and insufficient data for the function. - As we know CPSI is indeterministic with insufficient function data. - There is nothing special about diagonals in the function, - so CPSI paints them inaccurately. - The colors must be : - 000000ff 000000ff - 00ffffff xxxxxxxx (x = insufficient) - black black - blackred white - GS appears correct. - - - test07: aok - The test is buggy : it contains a wrong comment about colors - and insufficient data for the function. - As we know CPSI is indeterministic with insufficient function data. - There is nothing special about diagonals in the function, - so CPSI paints them inaccurately. - The colors must be : - 000000ff000000 ff00ffffffxxxx - xxxxxxxxxxxxxx xxxxxxxxxxxxxx (x = insufficient) - After tintTransfer : - 000000 ff00ff - xxxxxx xxxxxx (x = insufficient) - white magenta - black black - GS appears correct. - - - Test08, Test09: Test10: test1: aok - same as test04. - -12-14K-2 OK Minor differences in positions and character shapes - ADC - -12-14K-3 AOK Test06 : aok. The function cropping, same as 09-47G-2 Test10. - - - Test07 : aok. The function cropping - (a few different cropping than test06), same as 09-47G-2 Test10. - - - Test09 : aok. The function cropping - (a few different cropping than previous), same as 09-47G-2 Test10. - - - Test10 : aok. The function cropping - (a few different cropping than previous), same as 09-47G-2 Test10. - -12-14L-1 OK Minor differences in positions and character shapes - ADC - -12-14L-2 OK Minor differences in positions and character shapes - ADC - -12-14L-3 OK fixed. - -12-14L-4 OK Fixed by rev 7206 - -12-14M-1 OK fixed. - -12-14M-2 OK fixed. - -12-14M-3 OK fixed. - -12-14M-4 DIFF Test05: Tek has top half of cone solid dark gray, GS has light - gray (as in Test06). Assign: Igor - - - Test06: ok - fixed. - - - Test04, Test07: ok - Fixed by rev 7206 - Note: CPSI gets rangecheck errors on Test06, 07, 08. - -12-14M-5 OK fixed. - -12-14M-6 OK fixed. - -12-14M-7 OK fixed. - -12-14M-8 OK fixed. - -12-14N-1 OK Minor differences visually reviewed by RJJ - -12-14N-10 OK Minor differences in positions and character shapes - ADC - -12-14N-2 OK Minor differences in positions and character shapes - ADC - -12-14N-3 OK Minor differences in positions and character shapes - ADC - -12-14N-4 OK Minor differences in positions and character shapes - ADC - -12-14N-5 OK Fixed by rev 7206 - -12-14N-6 OK Fixed by rev 7206 - -12-14N-7 OK Minor differences visually reviewed by RJJ - -12-14N-8 OK Minor differences in positions and character shapes - ADC - -12-14N-9 OK fixed. - -12-14O-1 OK Minor differences in positions and character shapes - ADC - -12-14O-2 OK - -12-14O-3 OK Fixed with rev 7211. - -12-14O-4 OK Fixed as of rev. 7174 - Note: Tek tests 9-12 blank. - -12-14O-5 OK Fixed by rev 7206 - -12-14O-6 OK Minor differences in positions and character shapes - ADC - -12-14O-7 OK Minor differences in positions and character shapes - ADC - -12-14O-8 OK Minor differences in positions and character shapes - ADC - -12-14P-1 OK Minor differences in positions and character shapes - ADC - -12-14P-2 OK Minor differences visually reviewed by RJJ - -12-14P-3 OK Minor differences in positions and character shapes - ADC - -12-14P-4 AOK Fixed by rev 7206 - CPSI has a worse shading precision with a non-contigous color. - -12-14P-5 AOK CPSI problem with self-intersecting tensor shadings - Analyzed by Igor. - GS matches Distiller/Acrobat. - ADC - -12-14Q-1 OK Minor differences in positions and character shapes - ADC - -12-14Q-2 OK Minor differences in positions and character shapes - ADC - -12-14Q-3 OK Minor differences in positions and character shapes - ADC - -12-14Q-4 OK Fixed by rev 7206 - -12-14Q-5 OK Minor differences in positions and character shapes - ADC - - -12-14R-1 AOK Test02, 03, 06, 07, 08: aok. The function cropping, same as 09-47G-2 Test10. - CPSI is wrong. - -12-14R-2 AOK Worse smoothing with CPSI. - -12-14R-3 DIFF Analyzed by Igor. - - - Test07: - Analyzed by Igor. - The test looks buggy : duplicate DataSource. - CPSI uses the first DataSource (padded with zeros at end), - and GS uses the second one while constructing the shading dictionary. - GS interpretes the stream like this : - 000000ff 000000ff - 00ffffff 00000000 - so the shading is not completely black - it is 1/256 gray in one corner. - Note : lib/gs_*.ps files assume the usage of the last definition. - I recall that at least gs_ttf.ps depends on that. - Passing to Ray to decide what to do with it. - assign: Ray. - - - Test08: aok - CPSI ingores Encode. - It maps a haff of shading Domain outside (to negative values) - of the function domain, so that shading must look constant at - the riht half. That's what we see with GS. - - - Test09, 10, 11, 12: aok, same as Test07 except a different Encode. - Note : the vertical 'spike' in Test10 is a false human visual effect. - -12-14R-4 AOK Test1: aok - A worse smoothing with CPSI. - - - Test12: aok : - The function itself : - 000000 0000ff black blue - ff0000 00ff00 red green - ff00ff 00ff00 magenta green - ffff00 ffffff yellow white - It is linear, but the green component has Decode 0 3, - so it maps outside the color domain and - therefore it is cropped by the max color value 1. - Due to the color croppig it has a plattue - around the point where the green peak would apper. - Then the function domain is cropped - with 300/400 = 0.75 by X - and 500/600 = 0.83 by Y. - Therefore we don't see yellow and white. - GS paint it fine. - CPSI has a bad smoothing and a linear gradient instead the plattue. - -12-14S-1 OK Minor differences in positions and character shapes - ADC - -12-14S-2 OK Minor differences in positions and character shapes - ADC - -12-14S-3 OK Minor differences in positions and character shapes - ADC - -12-14T-1 OK fixed - -12-14T-2 OK fixed - -12-14U-1 OK - -12-14U-2 OK - -12-14U-3 OK Minor differences visually reviewed by RJJ - -13-01-1 OK Minor differences visually reviewed by RJJ - -13-01-2 OK - -13-01-3 OK Minor differences visually reviewed by RJJ - -13-01-4 OK Minor differences visually reviewed by RJJ - -13-01-5 OK - -13-01-6 OK Minor differences visually reviewed by HAS - -13-01-7 OK rev 7617. - -13-02-1 OK Minor differences visually reviewed by RJJ - -13-02-10 OK rev 7617. - -13-02-2 OK Minor differences visually reviewed by RJJ - -13-02-3 OK - -13-02-4 OK - -13-02-5 OK Fixed as of rev. 7583. - -13-02-6 OK Minor differences visually reviewed by RJJ - -13-02-7 OK Minor differences visually reviewed by RJJ - -13-02-8 OK - -13-02-9 OK Minor differences visually reviewed by HAS - -13-03-1 OK - -13-03-2 DIFF show error incomformity. - {{/a /b add } (abc) cshow} stopped - returns only true on the stack. assign: Peter - -13-03-3 OK Minor differences visually reviewed by RJJ - -13-03-4 OK Matches Tek hardcopy. PhotoPRINT appication we use for testing - redefines halftone operations as no-op, which is wrong and - cannot be considered a reference implementation. - Alex - -13-03-5 OK Minor differences visually reviewed by RJJ - -13-03-6 OK - -13-03-7 OK Color corrected by rev 7172. - -13-03-8 AOK Same as cash21, look30 : ustrokepath ending point. - -13-04-1 AOK Analyzed by Igor. - CPSI prints an incomplete page. - GS raster matches Tek except (1) different order - of keys in a dictionary forall (implementation dependent), - and (2) tek has an incorrect value FontType -1. - -13-04-2 OK - -13-04-3 OK - -13-05-1 OK - -13-05-2 OK - -13-05-3 AOK Adobe's interpreters accept a read-only font dictionary as a - valid argument of definefont and modify it anyway. This is a - bug that we will not emulate. (r7165 by Alex + comment by - Peter) - -13-05-4 OK Minor differences visually reviewed by HAS - -13-06-1 OK Fixed in rev. 7163. - Alex - -13-06-2 OK - -13-07-1 OK - -13-07-2 OK Adjust error reporting from findfont procedure to match - Distiller 5 and CET 13-06.PS.tek360 . The PhotoPrint product - is clearly wrong here leaving a few objects on the stack - besides the arguments when findfont fails. rev. 7164 - Alex - -13-07-3 OK - -13-08-1 OK Fixed by r7642. - -13-09-1 OK Fixed by r7642. - -13-10-1 OK - -13-10-2 OK - -13-10-3 OK - -13-10-4 OK - -13-10-5 OK Works for me in rev. 7543 - Alex. - -13-10-6 OK Minor differences visually reviewed by RJJ - -13-10-7 OK - -13-10-8 OK Minor differences visually reviewed by HAS. Color corrected by rev 7172. - -13-10-9 OK rev 7617. - -13-11-1 OK - -13-12-1 OK - -13-12-10 OK rev 7617. - -13-12-2 OK - -13-12-3 OK - -13-12-4 OK - -13-12-5 OK Minor differences visually reviewed by RJJ - -13-12-6 OK Matches Tek hardcopy, same as 13-03-4 - -13-12-7 OK Minor differences visually reviewed by RJJ - -13-12-8 OK - -13-12-9 OK Color corrected by rev 7172. - -13-13-1 OK - -13-13-2 OK - -13-13-3 OK Minor differences visually reviewed by HAS - (large diff count because of minor color diffs) - -13-13-4 OK Color corrected by rev 7172. - -13-13-5 OK Minor differences visually reviewed by HAS - -13-13-6 OK - -13-13-7 OK - -13-13-8 OK Color corrected by rev 7172. Fixed by rev 7617. - -13-14-1 AOK same as 13-04-1 - -13-14-2 OK - -13-14-3 OK - -13-15-1 OK - -13-15-2 OK Color corrected by rev 7172. - -13-15-3 OK - -13-15-4 OK - -13-15-5 OK Minor differences visually reviewed by HAS - -13-16-1 OK - -13-16-2 OK - -13-16-3 OK Minor differences visually reviewed by RJJ - -13-16-4 OK - -13-16-5 OK Minor differences visually reviewed by RJJ - -13-16-6 OK - -13-16-7 OK Minor differences visually reviewed by RJJ - -13-16-8 OK - -13-16-9 OK rev 7617. - -13-17-1 OK Corrected by 7152 and 7162. ADC - -13-17-2 OK Corrected by 7152 and 7162. ADC - -13-17-3 OK Corrected by 7152 and 7162. ADC - -13-17-4 OK Corrected by 7152 and 7162. ADC - -13-17-5 OK Minor differences visually reviewed by RJJ - -13-17-6 OK Corrected by 7152 and 7162. ADC - -13-17-7 OK Minor differences in positions and character shapes - ADC - -13-17-8 OK rev 7617. - -13-18-1 OK - -13-18-10 OK Minor differences in positions and character shapes - ADC - -13-18-11 OK rev 7617. - -13-18-2 OK - -13-18-3 OK - -13-18-4 OK - -13-18-5 OK - -13-18-6 OK - -13-18-7 OK - -13-18-8 OK - -13-18-9 OK - -13-19-1 AOK GS has a better stroke adjustment. not impotant. Analyzed by Igor. - -13-19-2 AOK Same as 13-19-1. Analyzed by Igor. - -13-19-3 AOK Same as 13-19-1. Analyzed by Igor. - -13-19-4 AOK Same as 13-19-1. Analyzed by Igor. - -13-19-5 OK Minor differences visually reviewed by RJJ - -13-19-6 OK Minor differences in positions and character shapes - ADC - -13-19-7 OK rev 7617. - -13-20-1 OK Minor differences in positions and character shapes - ADC - -13-20-2 OK - -13-20-3 OK Minor differences visually reviewed by RJJ - -13-20-4 OK - -13-20-5 OK Corrected by 7152 and 7162. ADC - -13-20-6 OK rev 7617. - -13-21-1 OK Fixed by r7642. - -13-22-1 OK - -13-22-2 OK Minor differences visually reviewed by RJJ - -13-22-3 OK Minor differences visually reviewed by RJJ - -13-22-4 OK Minor differences visually reviewed by RJJ - -13-22-5 OK Color corrected by rev 7172. - -13-22-6 OK rev 7617. - -13-23-1 OK GS matches CPSI and Tek when Adobe fonts are used. - With URW or UFST fonts, an extra line under /ordfeminine and - /ordmasculine characters shows as well as slightly different - appearance of other characters. This is a font issue and must - be resolved by the font vendor chosen for the implementation. - -13-24-1 OK - -13-24-2 AOK An unimportant difference in the character cache logics. Analyzed by Igor. - -13-24-3 OK Minor differences visually reviewed by RJJ - -13-24-4 OK Minor differences in positions and character shapes - ADC - -13-24-5 OK Minor differences visually reviewed by Igor. - -13-24-6 AOK Same as cash21, look30 : ustrokepath ending point. - -13-25-1 OK - -13-25-2 OK Fixed as of r7610 (when run with -dLOCALFONTS). - -13-25-3 OK - -13-26-1 OK Minor differences visually reviewed by RJJ - -13-26-2 OK - -13-26-3 OK - -13-26-4 OK Fixed in rev. 7562. - Alex - -13-26-5 OK Minor differences visually reviewed by RJJ - -13-26-6 OK Minor differences visually reviewed by RJJ - -13-26-7 OK Minor differences visually reviewed by RJJ - -13-26-8 AOK Minor differences in colors - ADC - -13-26-9 OK rev 7617. - -13-27-1 OK Minor differences visually reviewed by RJJ - -13-27-2 OK - -13-27-3 OK rev 7542. - -13-27-4 OK Minor differences visually reviewed by RJJ - -13-27-5 OK Minor differences visually reviewed by RJJ - -13-27-6 OK - -13-27-7 AOK Minor differences in colors - ADC - -13-27-8 OK rev 7617. - -13-28-1 OK Minor differences visually reviewed by RJJ - -13-28-2 OK Minor differences visually reviewed by RJJ - -13-28-3 OK - -13-28-4 OK rev 7542. - -13-28-5 OK Minor differences visually reviewed by RJJ - -13-28-6 OK Minor differences visually reviewed by RJJ - -13-28-7 OK Minor differences visually reviewed by RJJ - -13-28-8 AOK Minor differences in colors - ADC - -13-28-9 OK rev 7617. - -13-29-1 OK Minor differences visually reviewed by RJJ - -13-29-2 OK - -13-29-3 OK rev 7542. - -13-29-4 OK Minor differences visually reviewed by RJJ - -13-29-5 OK Minor differences visually reviewed by RJJ - -13-29-6 OK Minor differences visually reviewed by RJJ - -13-29-7 OK Minor differences visually reviewed by Igor. - -13-29-8 OK rev 7617. - -14-01-1 OK Minor differences visually reviewed by RJJ - -14-01-10 OK Minor differences visually reviewed by RJJ - -14-01-11 OK Minor differences visually reviewed by RJJ - -14-01-12 OK Minor differences visually reviewed by RJJ - -14-01-13 OK Minor differences visually reviewed by RJJ - -14-01-14 OK Minor differences visually reviewed by RJJ - -14-01-15 OK Minor differences visually reviewed by RJJ - -14-01-2 OK Minor differences visually reviewed by RJJ - -14-01-3 OK Minor differences visually reviewed by RJJ - -14-01-4 OK Minor differences visually reviewed by RJJ - -14-01-5 OK Minor differences visually reviewed by RJJ - -14-01-6 OK Minor differences visually reviewed by RJJ - -14-01-7 OK Minor differences visually reviewed by RJJ - -14-01-8 OK Minor differences visually reviewed by RJJ - -14-01-9 OK Minor differences visually reviewed by RJJ - -14-02-1 OK Minor differences visually reviewed by RJJ - -14-02-2 OK - -14-03-1 OK Minor differences visually reviewed by RJJ - -14-03-2 OK - -14-03-3 OK Minor differences visually reviewed by RJJ - -14-04-1 OK Minor differences visually reviewed by RJJ - -14-04-2 OK Minor differences visually reviewed by RJJ - -14-05-1 OK - -14-05-2 OK - -14-06-1 OK - -14-07-1 OK Minor differences visually reviewed by RJJ - -14-08-1 OK Color corrected by rev 7172. - -14-08-10 OK Corrected by 7152 and 7162. ADC - -14-08-11 OK Corrected by 7152 and 7162. ADC - -14-08-12 OK Corrected by 7152 and 7162. ADC - -14-08-13 OK Corrected by 7152 and 7162. ADC - -14-08-14 OK Corrected by 7152 and 7162. ADC - -14-08-15 OK Corrected by 7152 and 7162. ADC - -14-08-16 OK Corrected by 7152 and 7162. ADC - -14-08-17 OK A minor difference in color. Analyzed by Igor. - -14-08-18 OK Color corrected by rev 7172. - -14-08-19 OK A minor difference in color. Analyzed by Igor. - -14-08-2 OK Color corrected by rev 7172. - -14-08-20 OK A minor difference in color. Analyzed by Igor. - -14-08-21 OK A minor difference in color. Analyzed by Igor. - -14-08-22 OK A minor difference in color. Analyzed by Igor. - -14-08-23 OK Color corrected by rev 7172. - -14-08-24 OK A minor difference in color. Analyzed by Igor. - -14-08-3 OK A minor difference in color. Analyzed by Igor. - -14-08-4 OK Color corrected by rev 7172. - -14-08-5 OK A minor difference in color. Analyzed by Igor. - -14-08-6 OK Color corrected by rev 7172. - -14-08-7 OK A minor difference in color. Analyzed by Igor. - -14-08-8 OK Colors corrected by rev 7172. - -14-08-9 OK Corrected by 7152 and 7162. ADC - -14-09-1 OK - -14-09-2 OK - -14-09-3 OK - -14-09-4 OK - -14-10-1 OK - -14-10-2 OK - -14-10-3 OK - -14-10-4 OK - -14-11-1 OK Minor differences visually reviewed by RJJ - -14-11-2 OK Minor differences visually reviewed by RJJ - -14-12-1 OK - -14-12-2 OK - -14-12-3 AOK A glyph positioning difference. - Analyzed by Igor. - I believe it is CPSI problem. - A simplified test is placed to - peeves:/home/igor/pscet/mytests/14-12-3-Igor01.PS - With this test CPSI prints : - . - aaaa1: - Helvetica - has WMode - def:/Helvetica-Oblique - 1 - defined:1 - aaaa2: - Helvetica - nas no WMode - . - Thus the redefinition of the font Helvetica - is dropped when Helvetica-Oblique is redefined. - It is an incorrect behavior. - Due to that the cshow procedure prints - currentfont /WMode like this : - [1 1 /U /U /U /U 1 1 0 0 0 0] - The right result must be : - [1 1 1 1 0 0 1 1 0 0 0 0] - Using the wrong WMode, glyph placements - are wrong with CPSI. - Tek paints something different, - which is closer to Ghostscript, - but looks wrong again. - . - Some tips for those who wants to analyze it : - 1. Font_Dict is a FMap 2 font with 8 descendents : - 1.0. Times-Roman - 1.1. Type3WMode0 (paints rectangles with size depending on char code); - 1.2. Type3WMode1 (same as above but with WMode 1) - 1.3. Type0Font1 2 scalefont - the test doesn't use it. - 1.4. FMAP2 - a FMap 2 font [ Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique] - 1.5. FMAP4 [Symbol, Symbol 2 scalefont] - the test doesn't use it. - 1.6. FMAP5 [Courier, , , ] - the test doesn't use it. - 1.7. FMap6 [Helvetica, ...] - the test doesn't use it. - 2. All 1st level descendent fonts above has WMode = DescendentWMode = 1 - 3. Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique - are built into the font above aftyer redefinition with find&mod, - which changes WMode like this : - Helvetica WMode 1 - Helvetica-Bold WMode 0 - Helvetica-Oblique WMode 1 - Helvetica-BoldOblique WMode 0 - 4. The text string is decomposed like this : - 2A 2a 40A 40a 41A 41a 42A 42a 43A 43a 1A 1A - The 1st byte selects the 1st level descendent, - then it tripples the 2nd byte selects the 2nd level descendent. - 5. We believe that WMode of the leaf font only have sence. - -14-12-4 OK - -14-12-5 AOK Same as 14-12-3. - -14-12-6 AOK Same as 14-12-3. - -14-13-1 OK Minor differences visually reviewed by RJJ - -14-13-2 OK Minor differences visually reviewed by RJJ - -14-14-1 OK - -15-01-1 OK Fixed as of Nov 4 2005 - -15-01-2 OK Minor rasterizing differences. -Tor - -15-02-1 OK Fixed as of rev 7598. - -15-02-2 OK Minor differences visually reviewed by RJJ - -15-03-1 OK Fixed as of Nov 4 2005 - -15-04-1 AOK GS has -12dict- and CPSI has -11dict- in debug text. Different checksum. The - font dictionary debug for GS has one more key: /OrigFont. - I think these differences are harmless, and are not particularly easy to fix. If we do decide it needs fixing, Peter is a good choice. - Raph - -15-04-2 AOK Different checksum. The font dictionary debug for GS has more keys: /OrigFont and /FontInfo. - See 15-04-1 - Raph - -15-04-3 AOK Different checksum. The font dictionary debug for GS has one more key: /OrigFont. - See 15-04-1 - Raph - -15-05-1 OK Fixed when tested with 7210 - -15-05-2 OK Fixed when tested with 7210 - -15-05-3 OK Color corrected by rev 7172. - -15-06-1 OK Corrected by rev 7172. - -15-07-1 OK Minor rasterizing differences. -Tor - -15-08-1 OK Fixed in r7156 - Raph - -15-09-1 OK Minor rasterizing differences. Stroke width difference. -Tor - -15-09-2 OK Minor rasterizing differences. -Tor - -15-09-3 OK Minor rasterizing differences. -Tor - -15-10-1 OK Minor differences visually reviewed by RJJ - -15-10-2 OK Minor differences visually reviewed by RJJ - -15-10-3 OK Minor rasterizing differences. -Tor - -15-10-4 OK Minor rasterizing differences. -Tor - -15-11-1 OK Fixed by rev. 7806. - Alex - -15-14-1 OK Minor differences visually reviewed by RJJ - -15-15-1 OK Minor rasterizing differences. -Tor - -16-01-1 AOK glyphs 19-22 : Tiny gaps between almost adjoining black rectangles; - output will vary from device to device to device, and our rendering is valid. - Glyphs 207, 208: reverse video in Adobe output, likely Adobe bug. - Simplified tests are placed at - peeves:/home/igor/pscet/mytests/16-01/ - A patch for emulating such behavior is placed at - peeves:/home/igor/pscet/mypatches/16-01-Igor-01.txt - We won't commit that patch. - Suggesting to give the patch to the customer as a separate product. - -16-02-1 AOK Same as 16-01-1. - -16-03-1 OK Fixed by rev 7172. - -16-03-2 OK - -16-03-3 OK - -16-03-4 OK Now appears correct - Raph - -16-04-1 OK Fixed by rev. 7686 - Alex - -16-05-1 OK Color corrected by rev 7172 - -16-05-2 DIFF Three smallest sizes are slanted squares in gs, same shape as larger ones in Adobe. - Also USE_ADOBE_CMYK_RGB issue - Raph - assign: Ray - -16-05-3 OK Color corrected by rev 7172. - -16-06-1 OK trivial font rendering diff - Raph - -16-07-1 OK Checked by Raph - -16-08-1 OK Fixed in r7156 - Raph - -16-09-1 OK - -16-10-1 AOK Same as 16-01-1. - -16-10-2 AOK Same as 16-01-1. - -16-10-3 AOK Same as 16-01-1. - -16-11-1 OK Fixed by rev 7172. - -16-14-1 OK - -16-15-1 OK - -16-16-1 OK - -17-01-1 OK - -17-01-2 OK Fixed as of rev 7598. - -17-01-3 OK Fixed in rev 7630 (Peter) - -17-01-4 OK Fixed as of rev 7598. - -17-01-5 OK - -17-01-6 AOK Matches Tek. CPSI different. - -17-01-7 AOK Matches Tek and Distiller 5. CPSI is different and wrong, - The test exercises ineofill operator and can be easily checked - visually by modifying the test to fill the current path. - -17-01-8 OK - -17-02-1 OK - -17-02-2 OK Fixed as of rev. 7598. - -17-02-3 OK Same as 17-01-3 - -17-02-4 OK Fixed as of rev 7598. - -17-02-5 OK - -17-02-6 AOK Same as 17-01-6 but tests infill instead of ineofill. - Matches Tek and Distiller 5. CPSI is different and wrong, - -17-02-7 AOK Same as 17-01-6 but tests infill instead of ineofill. - Matches Tek and Distiller 5. CPSI is different and wrong, - -17-02-8 OK - -17-03-1 OK - -17-03-2 DIFF GS has curves where CPSI has straight lines. Also GS differs in marker symbols. - Note Tek has _different_ straight line pattern and marker symbols. - This is not identified as "Device Dependent" in the test. - curve flatness used to draw lines. Assign: ray - -17-03-3 OK Same as 17-01-3 - -17-03-4 OK Minor differences visually reviewed by RJJ - -17-03-5 DIFF Similar to 17-01-6 but tests instroke. The insideness testing is OK - but the pattern phase is different from Tek and CPSI. assign: Ray - -17-03-6 OK - -17-04-1 OK - -17-04-2 AOK The test is unreasonable. The test checks whether a point is in - the user path (using inueofill operator) but places many of - the points on the boundary of the path where insideness is - affected by rounding errors. When the point is inside the path, - a small black circle is drawn around the point. The test is - performed for different CTM. - - - Ghostscript skips some of the points at low resolution but - draws all expected points at 300 dpi and above. - - - CPSI, Tek, and Distiller 5 are all different and skip different - points depending on the current CTM. - Alex - -17-04-3 OK same as 17-02-3 - -17-04-4 OK - -17-04-5 OK - -17-05-1 OK - -17-05-2 AOK Similar to 17-04-2 but testing inufill. - Alex - -17-05-3 OK Same as 17-01-3 - -17-05-4 OK - -17-05-5 OK - -17-06-1 OK - -17-06-2 AOK Similar to 17-04-2 but testing inustroke. Placing the dots in - middle of the stroke is reasonable but some of the dots are - placed at the end of the line where their relative position - depends on the rounding errors. Ghostscript generates - correct results above 300 dpi. CPSI and Tek miss some - points, - Alex - -17-06-3 OK Fixed as of rev 7636. - -17-06-4 OK - -18-01A-1 AOK Minor difference in the font size. - Note: patterns are resolution dependent, - -18-01A-2 OK Minor differences visually reviewed by HAS. - -18-01A-3 OK Minor differences visually reviewed by RJJ - -18-01A-4 OK - -18-01A-5 OK Minor differences visually reviewed by RJJ - -18-01A-6 OK Minor differences visually reviewed by RJJ - -18-01A-7 OK Minor differences visually reviewed by RJJ - -18-01B-1 DIFF The word "FORM" in the magenta oval throughout the test - is white with cpsi and gray with gs. (repeats). - color saturation problem. - assign Tim - -18-01B-2 DIFF (18-01B-1) lower right graphic cpsi has red lines where gs has white. (assign Raph). - The locations of squares are shifted in this pattern. Distiller/Acrobat - 7.0 reports error 'incorrect number of values for setcolor operator'. - This is probaly related to the problem for 12-01-5. See Jan's - email analysis of that problem. (He reports a problem with pattern - shifts with patterns.) - -18-01C-1 OK Minor differences visually reviewed by RJJ - -18-02A-1 DIFF pattern size differs first row of graphics. assign Tim - -18-02A-2 OK Minor differences visually reviewed by HAS. Color corrected by rev 7172. - -18-02A-3 OK Minor differences visually reviewed by HAS. - -18-02A-4 OK Reviewed by Raph. Probably fixed by r7114. - -18-02B-1 OK Minor differences visually reviewed by HAS. - -18-02B-10 AOK 18-02A-4 repeat - Fill rule is ok, shadings sharper in GS than Adobe. - Raph - Per conversation with Ray, we have decided that our rendering - of these shadings (which have discontinuities) is more correct - than Adobe. Also note that for test 9, Tek and GS match, but - CPSI doesn't. - -18-02B-11 DIFF 18-02A-4 repeat - Fill rule is ok. Test 1, 4 shadings sharper in GS than Adobe. - Test 9-12 colors darker in Adobe than GS. - Assign Tim - -18-02B-12 DIFF 18-02A-4 repeat - Fill rule is ok. Test 1-3, 11 colors darker in Adobe. - Test 12 colors lighter in Adobe. - Raph - assign Tim - -18-02B-13 DIFF 18-02A-4 repeat - Fill rule is ok. Test 1-6 colors different as above. Raph - assign Tim - -18-02B-2 OK - -18-02B-3 OK Minor differences visually reviewed by HAS. - -18-02B-4 OK Minor differences visually reviewed by HAS. - -18-02B-5 OK Minor differences visually reviewed by RJJ - -18-02B-6 OK Minor differences visually reviewed by RJJ - -18-02B-7 DIFF 18-02A-4 repeat - Fill rule is ok. - Test 8-12 colors darker in Adobe than GS. - Raph - assign Tim - -18-02B-8 OK Probably fixed by r7114. - -18-02B-9 AOK 18-02A-4 repeat - Fill rule is ok, shadings sharper in GS than Adobe. - Raph - -18-02C-1 DIFF Partialy fixed by rev. 7738. - Adobe doesn't restore operands of rectfill operator when - an error happen in the PaintProc function but - Ghostscript does. assign: Alex - -18-02D-1 OK Fixed by rev. 7738. - Alex - -18-02E-1 DIFF much of postscript dump missing in gs. assign Ray - Ghostscript doesn't detect color operators in uncolored - pattern. - -18-02E-2 DIFF much of postscript dump missing in gs. assign Ray - Ghostscript doesn't detect color operators in uncolored - pattern. - -18-02F-1 OK Minor differences visually reviewed by HAS. - -18-02F-2 DIFF pattern in third row of graphics out of phase. assign Tim - -18-02F-3 DIFF 18-02A-4 repeat - repeat of AOK problem assign Tim - -18-02F-4 OK Fixed before Nov 3 (after Oct 2). - -18-02F-5 DIFF 18-02A-4 repeat - repeat of AOK problem assign Tim - -18-02G-1 DIFF strokepath different - assign: Igor. - - - pattern differs in 4th column of stars in the last box. - Analyzed by Igor. - See also 12-01-5. - A simplified test case is placed to - peeves:/home/igor/pscet/mytests/18-02G-1-Igor01.PS . - This is a general pattern implementation problem. - The test defines a pattern with TESTPROC, - and then applyes this pattern for creating another pattern - Inf71ColorPattern. Doing the 2nd step, Ghostscript - instantiates the 1st pattern in the 2nd pattern's space. - Contrary to that, CPSI instantiates the 1st pattern - in the device space when instantiating the 2st pattern. - Thus the overall pattern period with CPSI is a multiple - of periods of the 1st and the 2nd patterns. - This problem may be fixed for Ghostscript - with implementing high level patterns for - clist and raster devices. - It would be a significant development, - which we currently have no time for. - Passing to Ray for schedulling. - assign: Ray. - -18-02G-2 OK Fixed by r7123. - -18-02G-3 AOK Minor differences visually reviewed by HAS. - -19-01-1 OK - -19-01-2 OK - -19-02-1 OK - -19-02-2 OK - -19-02-3 OK - -19-03-1 OK - -19-03-2 OK - -19-03-3 OK - -19-04-1 OK - -19-04-2 OK - -19-05-1 OK Minor differences visually reviewed by RJJ - -19-05-2 OK Minor differences visually reviewed by RJJ - -19-05-3 OK - -19-06-1 OK - -19-06-2 OK - -19-07-1 OK - -19-07-2 OK - -19-08-1 OK - -19-08-2 OK - -19-09-1 OK - -19-09-2 OK - -19-09-3 OK - -19-10-1 OK - -19-10-2 OK - -19-11-1 OK Minor differences visually reviewed by RJJ - -19-11-2 OK - -19-12-1 OK Minor differences visually reviewed by RJJ - -19-12-2 OK - -19-13-1 OK Minor differences visually reviewed by RJJ - -19-13-2 OK Minor differences visually reviewed by RJJ - -19-13-3 OK - -19-14-1 OK Minor differences visually reviewed by RJJ - -19-14-2 OK - -20-01-1 OK Fixed in rev. 7712. - Alex - -20-01-2 AOK GS prints { 1 2 3 } [ 1 2 3 ] (1 2 3) where CPSI prints { 1 2 3 } [mark /1 -3array- ] and ( ) - i.e. CPSI modifies the content of the array arguments when operator >> fails. - Ghostscript matches Tek and Distiller 5. This is a bug in CPSI we don't - want to reproduce. - Alex - -20-01-3 OK - -20-02-1 OK Looks okay. -Tor - -20-02-2 OK Fixed by rev. 7829. - Alex - -20-02-3 OK Color corrected by rev 7172. - -20-03-1 OK - -20-03-2 OK - -20-04-1 OK Minor differences visually reviewed by RJJ - -20-04-2 OK Minor differences visually reviewed by RJJ - -20-04-3 OK Color corrected by rev 7172. - -20-05-1 OK - -20-05-2 OK - -20-06-1 OK - -20-06-2 OK - -20-07-1 OK - -20-07-2 OK - -20-08-1 OK - -20-08-2 OK - -20-08-3 OK - -20-09-1 OK - -20-09-2 OK - -20-09-3 OK - -20-10-1 OK - -20-10-2 OK - -20-11-1 OK fixed incidentally. - -20-11-2 OK fixed incidentally. - -20-11-3 OK - -20-12-1 OK Looks okay. -Tor - -20-12-2 OK - -20-13-1 OK Looks okay. -Tor - -20-13-2 OK Color corrected by rev 7172. - -20-14-1 OK GS matches Tek hardcopy. (Peter->Ray) - -20-14-2 OK Color corrected by rev 7172. - -20-15-1 OK Fixed by rev. 7713. - Alex - -20-15-2 OK - -20-16-1 OK Looks okay. -Tor - -20-16-2 OK Color corrected by rev 7172. - -20-17-1 OK - -20-17-2 OK - -20-18-1 OK Looks okay. -Tor - -20-18-2 OK Color corrected by rev 7172. - -20-19-1 OK Minor differences visually reviewed by RJJ - -20-19-2 OK Color corrected by rev 7172. - -20-20-1 OK GS matches Tek and CPSI as of rev. 7741. - -20-20-2 OK - -20-21-1 OK - -20-21-2 OK - -20-22-1 OK - -20-22-2 OK - -20-22-3 OK - -20-23-1 OK Tek and CPSI don't have /deviceinfo. Availability of this operator - on Ghostscript deprnds on gs_dps device. Rev. 7723 undefines it in - gs_cet.ps to pass the test regardless of the configuration. - Alex - -20-23-2 OK - -20-24-1 OK - -20-24-2 OK - -20-25-1 OK - -20-25-2 OK - -20-25-3 OK - -20-26-1 OK - -20-26-2 OK - -20-27-1 AOK This test check the content of the $error dictionary. - The content varies depending on the code executed before. - There's no error on CPSI, as it was stated before, The - value of /errorname is an error name, which is always - printed as white on black by the test program. - Alex - -20-27-2 OK - -21-01-1 OK - -21-01-2 OK - -21-02-1 OK Minor differences visually reviewed by RJJ - -21-02-2 OK Minor differences visually reviewed by RJJ - -21-02-3 OK Minor differences in positions and character shapes - ADC - -21-03-1 OK Minor differences in positions and character shapes - ADC - -21-03-2 OK Minor differences in positions and character shapes - ADC - -21-03-3 OK - -21-04-1 OK Minor differences in positions and character shapes - ADC - -21-04-2 OK Minor differences in positions and character shapes - ADC - -21-04-3 OK Minor differences in positions and character shapes - ADC - -21-05-1 OK Minor differences in positions and character shapes - ADC - -21-05-2 OK Minor differences in positions and character shapes - ADC - -21-05-3 OK Minor differences in positions and character shapes - ADC - -21-06-1 OK Minor differences in positions and character shapes - ADC - -21-06-2 OK Minor differences in positions and character shapes - ADC2 - -21-06-3 OK Minor differences in positions and character shapes - ADC - -21-07-1 OK Minor differences visually reviewed by RJJ - -21-07-2 OK Minor differences in positions and character shapes - ADC - -21-07-3 OK Minor differences in positions and character shapes - ADC - -21-08-1 OK Minor differences visually reviewed by RJJ - -21-08-2 OK Minor differences visually reviewed by RJJ - -21-08-3 OK Minor differences in positions and character shapes - ADC - -21-09-1 OK - -21-09-2 OK - -21-10-1 OK Minor differences in positions and character shapes - ADC - -21-10-2 OK Minor differences in positions and character shapes - ADC - -21-11-1 OK - -21-11-2 OK Fixed as of rev 7598. - -21-11-3 OK Fixed as of rev 7616. - -21-11-4 OK - -21-11-5 OK - -21-11-6 DIFF Differences in error messages for operator token - ADC - assign Peter - -21-11-7 OK Corrected by 7152 and 7162. ADC - -22-01-1 OK - -22-01-2 OK - -22-02-1 OK - -22-02-2 OK - -22-03-1 OK - -22-03-2 OK - -22-04-1 OK - -22-04-2 OK - -22-05-1 OK Minor differences visually reviewed by RJJ - -22-05-2 OK - -22-06-1 OK - -22-06-2 OK - -22-07-1 OK - -22-07-2 OK - -22-07-3 OK - -22-08-1 OK Minor differences visually reviewed by RJJ - -22-08-2 OK Minor differences visually reviewed by RJJ - -22-08-3 OK Visually OK SK small variations in tiny colour cube. - -22-09-1 OK - -22-09-2 OK - -22-10-1 OK Minor differences visually reviewed by HAS - -22-10-2 OK - -22-10-3 OK - -22-11-1 OK - -22-11-2 OK - -22-12-1 OK Minor differences visually reviewed by RJJ - -22-12-2 OK Minor differences visually reviewed by RJJ - -22-13-1 OK - -22-13-2 OK - -22-13-3 OK - -22-13-4 OK - -23-01-1 OK - -23-01-2 OK - -23-02-1 OK - -23-02-2 OK - -23-03-1 AOK Device Dependent: Test checks for 'bytesavailable' on 'currentfile'. - This is generally not supported from %stdin. - -23-03-2 OK - -23-04-1 OK - -23-04-2 OK - -23-05-1 OK - -23-05-2 OK - -23-06-1 OK - -23-06-2 OK - -23-07-1 OK Fixed by rev. 7442 - -23-07-2 AOK There is still a diff in 23-07-2 in that the contents of our resource - category dictionaries (in this case, the Generic dictionary) are different - from the Adobe interpreters: we and Adobe have different implementation-specific - (non-PLRM) entries, and the PLRM-documented procedures (FindResource, etc.) - are different. This is inherently implementation-dependent and does not - affect any real program, so no further changes are needed. (Peter) - -23-07-3 OK Fixed by rev. 7442 - -23-07-4 OK - -23-08-1 OK - -23-09-1 DIFF The first bytesavailable diff is identified as "highly device dependent". - As such, I recommend discounting it. No real program will rely on the - result. - - - The two invalidaccess diffs occur because the reference implementation does - not allow PostScript programs to open files for writing. This is not a gs - bug, but it does suggest that gs should provide some way to indicate/detect - that it is running in an embedded environment with no (writable) filesystem. - Does this exist already? - - - The remaining 3 diffs occur because gs implements %null as a special file - name and the reference implementation apparently doesn't, per a previous - e-mail. - - - assign: ray - -23-10-1 AOK Device Dependent: GS looks like it is working similar to CPSI ot - Tek, but all three differ. RJJ - -23-10-2 OK - -23-11-1 OK Minor differences visually reviewed by RJJ - -23-12A-1 OK - -23-12A-2 OK - -23-12A-3 AOK The discrepancies are in the length of the encoded - string produced by the ASCII85Encode and - RunLengthEncode filter respectively. These filters - have some discretion in their output -- ASCII85Encode - must insert a \n at least every 80 characters, but may - insert one more often, and RunLengthEncode is not - required to produce maximum-length runs -- and it - appears that gs's implementation of these filters - produces output that is 1 byte shorter than Adobe's in - some cases. gs's output is (also) correct -- the CET - verifies it by decoding it and comparing against the - original. (peter) - -23-12A-4 AOK same resolution as 23-12A-3. - -23-12B-1 DIFF GS gets "-file- ( ioerror --readstring--" on FAX_6 test. Last - image of top row missing, others may be shifted. assign: Peter - -23-12C-1 OK - -23-12C-2 OK - -23-12C-3 OK - -23-12D-1 OK Fixed incidentally - -23-12D-2 OK Fixed incidentally - -23-12D-3 OK Fixed incidentally - -23-12D-4 OK Fixed incidentally - -23-12E-1 AOK Device Dependent: Test says "length can vary due to multiple valid - methods". GS differs by 1 to 5 in results (hope that's close enough) - RJJ - -23-12E-2 AOK (Peter) 7605 fixes ioerror and incorrect output problems. - - - "There are still discrepancies in the length of the - compressed data, for the same reason as 23-12A-3 et - al. In this case, gs's implementation is slightly - inferior to Adobe's (about 6% larger compressed data - in the worst case on the CET page), probably because - in the mixed 1- and 2-D case, we don't bother to - compress each line both ways and use whichever method - produces the smaller output." - -23-12E-3 OK Device Dependent: minor position/stairstep differences, but visually - equivalent to Tek. RJJ. - -23-12E-4 OK Device Dependent: minor position/stairstep differences, but visually - equivalent to Tek. RJJ. - -23-12E-5 DIFF GS has lower three graphics 'squashed' horizontally. assign: Ray - -23-12E-6 DIFF GS has lower three graphics as .step-pyramids'. assign: Ray - -23-12E-7 OK - -23-12F-1 OK - -23-12G-1 AOK same as 23-12A-3 (peter) - -23-12G-2 AOK same as 23-12A-3 (peter) - -23-12G-3 OK - -23-12H-1 OK - -23-12I-1 OK. Fix from Peter - -23-12I-2 OK. Fix from Peter - -23-12J-1 OK - -23-12J-2 OK - -23-12J-3 OK - -23-12J-4 OK - -23-12K-1 OK Fixed as of r7500. - -23-12K-2 OK Fixed by rev 7808. - Alex - -23-12L-1 AOK same as 23-12A-3 - -23-12M-1 AOK same as 23-12A-3 - -23-12N-1 AOK same as 23-12A-3 - -23-12O-1 AOK same as 23-12A-3 - -23-12O-2 OK Fixed by rev 7489. - -23-12P-1 AOK same as 23-12A-3 - -23-12P-2 OK Fixed by rev 7489. - -23-12Q-1 OK - -23-12R-1 OK - -23-12S-1 OK - -23-12T-1 OK - -23-12U-1 OK Fixed as of r7500. - -23-12V-1 OK Fixed as of r7500. - -23-12W-1 OK Fixed as of r7500. - -23-12W-2 OK Fixed as of rev 7636. - -23-12W-3 OK Minor differences visually reviewed by RJJ - -23-12W-4 OK Matches Tek hardcopy. CPSI-based PhotoPrint product ignores - sethalftone and cannot be a reference implementation here. - -23-12W-5 OK Fixed by rev 7149. - -23-12W-6 OK Fixed as of r7500. - -23-13-1 OK Fixed as of r7610 (when run with -dLOCALFONTS). - -23-13-2 AOK Device Dependent: GS has more entries for Filter, ColorSpace - page fills before ImageType and PatternType shown. - -23-13-3 DIFF Device Dependent: GS has different Resource Categories and also - has different number of columns. Assign: Ray for further analysis - -23-13-4 AOK Ghostscript has extra keys in the font dictionary. PLRM says that - implementations can add specific keys. Rev. 7724 - Alex - -23-13-5 OK Fixed by rev 7442. - -23-13-6 OK - -23-14-1 OK - -23-14-2 OK - -23-15-1 OK - -23-15-2 OK - -23-16-1 OK Minor differences visually reviewed by RJJ - -23-16-2 OK - -23-17-1 OK Minor differences visually reviewed by RJJ - -23-17-2 AOK Probably fixed with 23-17-3 - -23-17-3 AOK Fixed see 23-29-2, 23-36-3 and 23-36-4 - -23-18-1 OK Minor differences visually reviewed by RJJ - -23-18-2 OK - -23-19-1 OK - -23-19-2 OK - -23-20-1 OK Fixed by rev. 7809. - Alex - -23-20-2 OK - -23-21-1 OK Fixed in rev. 7140. - Alex. - -23-21-2 OK - -23-22-1 OK Fixed in rev. 7143. - Alex. - -23-22-2 OK - -23-23-1 OK Fixed in rev. 7144. - Alex. - -23-24-1 OK - -23-24-2 OK - -23-25-1 DIFF GS gets 'undefinedfilename' error. Tek and CPSI do not. Assign: Ray - -23-25-2 DIFF GS gets 'undefined' error during defineresource. (PLRM3 requires - CIDSystemInfo). Device Dependent: CPSI doesn't define Localization - category. Needs Tek hardcopy. Assign: Ray - -23-25-3 DIFF GS close to Tek, but stack contents when 'stackunderflow' reported - differs. GS reports 'undefinedresource' vs. 'typecheck' of Tek. - Different error and stack from ((FNT1) {cvn} () resourceforall). - Needs Tek hardcopy. Assign: Ray - -23-25-4 OK - -23-25-5 OK - -23-25-6 OK - -23-25-7 OK - -23-26-1 OK - -23-26-2 OK Fixed before Oct 2. - -23-26-3 AOK Device Dependent: GS has more entries for Filter, ColorSpace - page fills before ImageType and PatternType shown. Same as 23-13-2. - -23-26-4 OK Adobe interpreters have resoursestatus as an operator but report errors - in the executable name. Since rev. 7619 we do the same. - Alex - -23-26-5 OK - -23-26-6 OK - -23-28-1 OK Fixed in rev. 7146. - Alex. - -23-29-1 OK - -23-29-2 OK fixed in rev. 7232 (Peter) - -23-29-3 OK - -23-30-1 OK - -23-30-2 OK - -23-31-1 OK Matches Tek hardcopy. RJJ (CPSI differs) - -23-31-2 OK - -23-32-1 OK - -23-32-2 DIFF 'token' error inconformity. - Environment dependent (a virtual address in the printing). - assign: Peter - -23-32-3 OK Fixed as of rev 7598. - -23-32-4 OK fixed in rev 7672 (Peter) - -23-32-5 OK - -23-32-6 OK - -23-33-1 AOK Device Dependent: status and number of Font, Encoding, and - ColorSpaceFamily resources pre-loaded differs between CPSI and - Tek and Ghostscript. (this is not a problem). - -23-33-2 OK GS matches Tek hardcopy. CPSI shows "0 -1 T" in last line. - -23-33-3 OK Fixed in rev. 7620 - Alex - -23-33-4 OK Fixed in rev. 7620 - Alex - -23-33-5 OK Fixed in rev. 7619; See 23-26-4 for details. - Alex. - -23-33-6 OK - -23-34-1 OK - -23-34-2 OK - -23-35-1 OK - -23-35-2 OK - -23-35-3 OK - -23-36-1 OK - -23-36-2 OK Fixed in r7631 Peter - -23-36-3 AOK fixed in rev. 7232 (Peter) - -23-36-4 OK fixed in rev. 7232 (Peter) - -23-37-1 OK - -23-37-2 OK - -23-37-3 OK - -24-01-1 OK - -24-01-2 OK - -24-02-1 OK - -24-02-2 OK - -24-02-3 OK - -24-03-1 OK - -24-03-2 OK - -24-04-1 OK - -24-04-2 OK - -24-05-1 OK Fixed by Alex, rev. 7131. - -24-05-2 AOK Fixed by Alex, rev. 7131. except that Adobe interpreters have - a bug when "1234556789 10 ( ) cvrs" restores the stack as - "123456789 ( ) ( )" Ghostscript doesn't have this bug. - Since we don't want to put in a bug, this will be an anomaly. - -24-05-3 OK - -24-06-1 OK - -24-06-2 OK Fixed by Alex, rev. 7131. - -24-06-3 OK - -24-07-1 OK - -24-07-2 OK - -24-08-1 OK Minor differences visually reviewed by RJJ - -24-08-2 OK - -24-08-3 OK - -24-09-1 OK - -24-09-2 OK - -24-09-3 OK - -24-10-1 OK - -24-10-2 OK - -24-10-3 OK - -24-11-1 OK Minor differences visually reviewed by RJJ - -24-11-2 OK - -24-11-3 OK - -24-12-1 OK Minor differences visually reviewed by RJJ - -24-12-2 OK - -24-13-1 OK - -24-13-2 OK - -24-13-3 OK Fixed by r7642. - -24-14-1 OK - -24-14-2 OK - -25-01-1 OK - -25-01-2 OK - -25-02-1 OK - -25-02-2 OK - -25-03-1 OK Minor differences visually reviewed by RJJ - -25-03-2 OK - -25-04-1 OK Minor differences visually reviewed by RJJ - -25-04-2 OK - -25-05-1 OK GS matches Tek hardcopy. Fixed by rev 7140. - GS has more accurate (and correct) sin/cos functions than CPSI - -25-05-2 OK - -25-06-1 OK - -25-06-2 OK - -25-07-1 OK Fixed by rev 7139. - -25-07-2 OK - -25-08-1 OK Minor differences visually reviewed by RJJ - -25-08-2 OK - -25-09-1 OK Fixed by rev 7225. - -25-09-2 OK Fixed by rev 7224. - -25-10-1 OK GS matches Tek hardcopy. Fixed by rev 7140. - -25-10-2 OK - -25-11-1 OK GS matches Tek hardcopy. Fixed by rev 7140. - GS has more accurate (and correct) sin/cos functions than CPSI - -25-11-2 OK - -25-12-1 OK - -25-12-2 OK - -25-13-1 OK Fixed - Alex. - -25-13-2 OK - -25-14-1 OK - -25-14-2 OK - -25-15-1 OK - -25-15-2 OK - -25-16-1 OK - -25-16-2 OK - -25-16-3 OK - -25-17-1 OK - -25-17-2 OK - -25-18-1 OK GS matches Tek hardcopy. Fixed by rev 7140. - GS has more accurate (and correct) sin/cos functions than CPSI - -25-18-2 OK - -25-19-1 OK Works for me in rev. 7149. - -25-19-2 OK - -25-20-1 OK - -25-20-2 OK - -25-21-1 OK - -25-21-2 OK - -25-22-1 OK - -25-22-2 OK - -26-01-1 OK - -26-01-2 OK - -26-01-3 OK - -26-02-1 OK - -26-02-2 OK - -26-03-1 OK - -26-03-2 OK Minor differences visually reviewed by RJJ - -26-03-3 OK - -26-04-1 OK - -26-04-2 OK - -26-05-1 OK - -26-05-2 OK - -26-05-3 OK - -26-06-1 OK - -26-06-2 OK - -26-06-3 OK - -26-07-1 OK - -26-07-2 OK - -26-07-3 OK - -26-08-1 OK - -26-08-2 OK - -26-09-1 OK - -26-09-2 OK - -26-10-1 OK - -26-10-2 OK - -26-11-1 OK - -26-11-2 OK - -26-11-3 OK - -26-12-1 OK - -26-12-2 OK - -26-13-1 OK - -26-13-2 OK - -26-13-3 OK - -27-01-1 OK Minor differences visually reviewed by RJJ - -27-01-2 OK - -27-02-1 OK Adobe has upper cache limit of 1e8 bytes. - Rev. 7746 does the same in CPSI compatibility mode. - Alex - -27-02-2 OK - -27-03-1 OK Fixed as of rev 7598. - -27-03-2 AOK test unreasonable: - This page enumerates all the IODevices, arbitrarily selects the last one, - and then runs the GIF test, checking whether the currentdevparams values for - that IODevice change as a result of running the test procedures. This is - dependent both on the set of IODevices (which is implementation-dependent, - although gs could be expected to include at least the non-hardware-dependent - ones documented in the PLRM3, which I believe it does) and the order in - which they are enumerated by /IODevice resourceforall (which is totally - implementation-dependent). - - - It appears that in the reference output, the last-enumerated IODevice is one - whose devparams values change somewhat unpredictably -- probably %Calendar%. - In the gs output, it's one whose devparams values don't change -- i.e. any - of the others! (peter) - -27-04-1 DIFF Installation dependent (FontResourceDir). - Inconforming currentsystemparams. Analyzed by Igor. - assign: Ray for further analyzis. - -27-04-2 OK - -27-05-1 DIFF Inconforming currentuserparams. Analyzed by Igor. - assign: Ray for further analyzis. - -27-05-2 OK memo36 - setvmthreshold; cash18 ucachestatus; - assign: Ray for further analyzis. - more15 - same as currentstrokeadjust in 09-49D-3 - peter writes: - These CET files will not run on my 64-bit build (they expect to be able to - 'cvs' any integer into a 12-character string), and I don't seem to be able - to get gcc to produce 32-bit output, even with Ralph's help. Please - reassign these files. - -27-06-1 OK Fixed in rev. 7157 - Alex. - -27-06-2 OK - -27-07-1 AOK Fixed by rev. 7733 - Alex - Alternate use of --setcacheparams-- and /setcacheparams in error - messages is an obvious bug in Adobe interpreters that we won't - reproduce. - -27-07-2 OK - -27-08-1 OK Fix error reporting for setdevparams operator, rev. 7161. - Alex - -27-08-2 OK - -27-09-1 DIFF Same as 27-04-1. Analyzed by Igor. - assign: Ray for further analyzis. - -27-09-2 DIFF Same as 27-04-1. Analyzed by Igor. - assign: Ray for further analyzis. - -27-09-3 OK Minor differences visually reviewed by RJJ - -27-09-4 OK - -27-10-1 OK Minor differences visually reviewed by RJJ - -27-10-2 OK - -27-11-1 DIFF Inconforming currentuserparams. See 27-05-1. Analyzed by Igor. - assign: Ray for further analyzis. - -27-11-2 OK Minor differences visually reviewed by RJJ - -27-11-3 OK - -27-12-1 DIFF ucachestatus differs. Analyzed by Igor. - assign: Raph. - -27-12-2 DIFF Same as 27-05-2. Analyzed by Igor. assign: Ray.. - -28-01-1 OK - -28-01-2 OK - -28-02-1 OK - -28-02-2 OK Fixed before Nov 4 2005 (after Oct 2) - -28-02-3 OK - -28-03-1 AOK The following differences remain: - 1. names of internal operators are different - 2. execution stack od 49 elements doesn't fit into 40-element - arrays provided by the test causing different errors. - Rev. 7730 - Alex - -28-03-2 OK - -28-04-1 OK - -28-04-2 OK - -28-05-1 OK - -28-05-2 OK Fixed by rev. 7725 - -28-05-3 OK - -28-06-1 AOK Implementation Dependent: Section 6.3 - SYNTAX 2. The PLRM says the - the order of dict enumeration by 'forall' is "arbitrary". - -28-06-2 OK - -28-06-3 OK - -28-07-1 OK - -28-07-2 OK - -28-07-3 OK - -28-08-1 OK - -28-08-2 OK - -28-09-1 OK Minor differences visually reviewed by RJJ - -28-09-2 OK Visually reviewed by RJJ - (previous report of '1' in more 15 is without gs_cet.ps). - -28-10-1 OK Fixed by rev. 7727. - Alex - -28-10-2 OK Minor differences in boxed black/white 'T' 'F' glyphs, font renderer ufst. - -28-11-1 OK Minor differences visually reviewed by RJJ - -28-11-2 OK Visually reviewed by RJJ - -28-12-1 OK - -28-13-1 OK Minor differences visually reviewed by RJJ - -28-13-2 OK Visually reviewed by RJJ - -28-14-1 OK Fixed by r7115. - -28-14-2 OK Minor differences visually reviewed by RJJ - -29-02-1 OK Minor differences visually reviewed by RJJ - -29-02-2 OK Fixed by rev. 7716. Ghostscript matches Tek and CPSI except - that CPSI-based PhotoPrint doesn't implement copypage and skips - pages 3 and 4. - Alex - -29-02-3 OK See 29-02-2. - -29-02-4 OK See 29-02-2. - -29-02-5 OK See 29-02-2. - -29-02-6 OK See 29-02-2. - -29-02-7 OK See 29-02-2. - -29-02-8 OK See 29-02-2. - -29-03-1 DIFF Device Dependent. Too many InputAttributed. Analyzed by Igor. assign: Ray. - -29-03-2 DIFF Device Dependent. OutputPage not known. Analyzed by Igor. assign: Ray - -29-03-3 DIFF Device Dependent. currentpagedevice different. Analyzed by Igor. assign: Ray - -29-03-4 DIFF Many conformity tests fail. Analyzed by Igor. - The test expects currentpagedevice to return the same dictionaty each time. - assign: Alex. - -29-05-1 OK Make the spot function in the high resolution halftone readable - to accomodate the test logic. Ghostscript matches Tek and - Distiller 5. CPSI-based PhotoPrint product redefines halftone - operations as no-op and cannot serve as a reference - implementation here. - Alex - -29-05-2 OK - -29-05-3 OK - -29-07A-1 OK - -29-07A-2 OK - -29-07A-3 OK Device Dependent. CPSI ignores setcolortransfer to perform - image negation. Ghostscript matches Tektronix hardcopy. - -29-07A-4 OK corrected with gs_cet.ps that only has 'letter' PageSize - in InputAttributes dictionary. - -29-07A-5 OK corrected with gs_cet.ps that only has 'letter' PageSize - in InputAttributes dictionary. - -29-07A-6 AOK Device Dependent: Error message differs. Ghostscript gives - "configurationerror in setpagedevice", CPSI gives bogus - "undefinedfilename in file" on this "Page 10 experiment" - -29-07B-1 OK Verified visually by RJJ - -29-07B-10 OK Verified visually by RJJ. CPSI ignores NumCopies. - cpsi/29-07B-10 missing - -29-07B-11 OK Verified visually by RJJ. CPSI ignores NumCopies. - cpsi/29-07B-11 missing - -29-07B-12 OK Verified visually by RJJ. CPSI ignores NumCopies. - cpsi/29-07B-12 missing - -29-07B-2 DIFF GS shifts output up and left, CPSI and Tek ignore Margins [ -9 9 ] - assign ray. - -29-07B-3 DIFF GS shifts output down and right, CPSI and Tek ignore Margins [ 9 -9 ] - assign ray. - -29-07B-4 OK Verified visually by RJJ - -29-07B-5 OK Verified visually by RJJ - -29-07B-6 OK Verified visually by RJJ - -29-07B-7 OK Verified visually by RJJ. CPSI ignores NumCopies. - -29-07B-8 OK Verified visually by RJJ. CPSI ignores NumCopies. - -29-07B-9 OK Verified visually by RJJ. CPSI ignores NumCopies. - -29-07C-1 OK - -29-07C-2 DIFF Device Dependent: CPSI shows offset page. GS shows 'undefined' - error. Tektronix shows 'configurationerror'. May be a default - Policy setting vs. CPSI. GS should issue 'configurationerror' - Assign: Ray. - -29-07C-3 AOK Device Dependent: Ghostscript matches Tektronix hardcopy and - gives 'configurationerror'. CPSI output is offset. - -29-07C-4 DIFF Device Dependent: CPSI shows offset page. GS shows 'undefined' - error. Tektronix shows 'configurationerror'. May be a default - Policy setting vs. CPSI. GS should issue 'configurationerror' - Assign: Ray. - -29-07C-5 AOK Device Dependent: Ghostscript matches Tektronix hardcopy and - gives 'configurationerror'. CPSI output is offset. - -29-07C-6 DIFF Device Dependent: CPSI shows offset page. GS shows several - parameters with value '1'. Tektronix shows only "/PageSize 1" - Assign: Ray. - -29-07C-7 AOK Device Dependent: Ghostscript matches Tektronix hardcopy and - gives 'configurationerror'. CPSI output is offset. - -29-07C-8 DIFF Device Dependent: CPSI shows offset page. GS offset differs. - Tektronix hardcopy shows << /PageSize 3 >> with offset that - might be the same as CPSI (clipping right edge after 's' of - 'setpagedevice' in the lower right banner block). - assign ray - -29-07C-9 DIFF Device Dependent: CPSI shows offset page. GS offset differs. - Tektronix hardcopy shows << /PageSize 3 >> with offset that - might be the same as CPSI (clipping right edge after 's' of - 'setpagedevice' in the lower right banner block). - assign ray - -29-07C-10 DIFF Device Dependent: CPSI shows offset page. GS has no offset - Tektronix hardcopy shows << /PageSize 3 >> with offset that - might be the same as GS (no clipping). - assign ray - -29-07C-11 DIFF Device Dependent: CPSI shows offset page. GS has no offset - Tektronix hardcopy shows << /PageSize 3 >> with offset that - might be the same as GS (no clipping). - assign ray - -29-07D-1 OK - -29-07D-2 OK - -29-07D-3 OK corrected with gs_cet.ps that only has 'letter' PageSize - in InputAttributes dictionary. - -29-07D-4 OK - -29-07D-5 DIFF Ghostscript is producing a page when OuputPage is 'false'. - cpsi/missing output for 'Page 5 experiment'. - assign ray - -29-07D-6 DIFF Device Dependent: Ghostscript is honoring 'PageOffset' - Adobe ignores this. correct by modifying setpagedevice. - Assign: Ray - -29-07D-7 DIFF Device Dependent: Ghostscript is honoring 'PageOffset' - Adobe ignores this. correct by modifying setpagedevice. - Assign: Ray - -29-07E-1 OK - -29-07E-2 AOK GS rotates the image to fit the page, same as CPSI when - rotated. PageSize Policy==7 of the PLRM says: "Positioning - of the page image on the medium is device-dependent and - unpredictable. This policy exists solely for use in the - emulations of certain LanguageLevel 1 compatibility operators - that perform media selection and page device setup separately. - ... - Because its behavior violates the PostScript page device model, - documents that use this policy are not portable; for this reason, - it should never be used directly in a page description." - -29-07E-3 AOK See explanation under 29-07E-2. - -29-07E-4 DIFF GS does not generate a configuration error. Tek does. PLRM says - > 5 units difference should generate configurationerror with - Policy == 7. GS rotates the page and generates a larger raster. - Assign: Ray (Peter can thank me that I didn't give this to him). - -29-07E-5 DIFF Same as 29-07E-4. Assign: Ray - -29-07E-6 DIFF Same as 29-07E-4. Assign: Ray - -29-07E-7 OK - -29-07F-1 OK - -29-07F-2 OK Matches Tek hardcopy. RJJ (CPSI differs / wrong) - -29-07F-3 OK - -29-07F-4 OK - -29-07F-5 OK - -29-07F-6 OK - -29-07F-7 OK Matches Tek hardcopy. RJJ (CPSI differs / wrong) - -29-07F-8 OK Matches Tek hardcopy. RJJ (CPSI differs / wrong) - -29-07G-1 OK - -29-07G-2 OK - -29-07G-3 OK - -29-07G-4 OK - -29-07G-5 OK - -29-07G-6 OK - -29-07G-7 OK - -29-07G-8 OK - -29-07H-1 OK - -29-07H-2 OK - -29-07H-3 OK - -29-07H-4 OK - -29-07H-5 OK - -29-07H-6 OK - -29-07H-7 OK - -29-07H-8 OK - -29-07I-1 OK - -29-07I-2 OK - -29-07I-3 OK - -29-07I-4 OK - -29-07I-5 OK - -29-07I-6 OK - -29-07I-7 OK - -29-07I-8 OK - -29-07I-9 OK - -29-07J-1 OK - -29-07J-2 OK - -29-07J-3 OK - -29-07J-4 OK - -29-07J-5 OK - -29-07J-6 OK - -29-07J-7 OK - -29-07J-8 OK - -29-07J-9 OK - -29-07K-1 OK - -29-07K-2 OK - -29-07K-3 OK - -29-07K-4 OK - -29-07K-5 OK - -29-07K-6 OK - -29-07K-7 OK - -29-08-1 OK - -29-08-2 OK - -29-08-3 OK Minor differences visually reviewed by RJJ - -29-08-4 OK Visually reviewd by RJJ. CPSI doesn't do #copies. - Ghostscript matches Tektronix hardcopy. - -29-08-5 OK Visually reviewd by RJJ. CPSI doesn't do #copies. - Ghostscript matches Tektronix hardcopy. - -29-08-6 OK Visually reviewd by RJJ. CPSI doesn't do #copies. - Ghostscript matches Tektronix hardcopy. - cpsi/29-08-6 missing - -29-08-7 OK Visually reviewd by RJJ. CPSI doesn't do #copies. - Ghostscript matches Tektronix hardcopy. - cpsi/29-08-7 missing - -30-01-1 OK - -30-01-2 OK - -30-02-1 OK - -30-02-2 OK - -30-03-1 AOK These discrepancies occur because - /show load gcheck - returns true in gs and false in the reference output. This is an unarguable - bug in the reference interpreters: see the documentation for gcheck in the - PLRM3. (peter) - -30-03-2 OK - -30-04-1 OK - -30-04-2 OK Fixed by rev 7439. - -30-04-3 OK - -30-04-4 OK fixed in packed array colorspace fix (ray) don't recall the rev. - -30-04-5 OK - -30-05-1 OK - -30-05-2 OK - -30-06-1 AOK These discrepancies occur because - /show load gcheck - returns true in gs and false in the reference output. This is an unarguable - bug in the reference interpreters: see the documentation for gcheck in the - PLRM3. (peter) - -30-06-2 OK - -30-07-1 OK Fixed by r7642. - -30-07-2 DIFF /GlobalFontDirectory /Type3Font1 known gs=true, cpsi=false. assign Peter. - -30-07-3 DIFF gs missing '1' for gray33. Assign Peter. - -30-08-1 OK Fixed by r7642. - -30-08-2 DIFF same as 30-07-2 assign Peter. - -30-08-3 DIFF same as 30-07-3 assign Peter - -30-09-1 OK fixed in Revision 7233 - -30-09-2 OK - -30-10-1 OK fixed in Revision 7233 - -30-10-2 OK - -30-11-1 OK - -30-11-2 AOK Environment dependent. - GS prints different numbers for every test in GLOBINT. - The number printed is the VM usage for the test. - -31-01-1 DIFF Attributes differ (bottom of page filetype). - (%stdin)(r) file is global on GS and local on Adobe. - Also see bug 687682, where a similar problem was reported earlier. - Assign: Ray - -31-01-10 OK - -31-01-2 OK Works for me in rev. 7453. - Alex - -31-01-3 OK Minor differences visually reviewed by RJJ - -31-01-4 OK - -31-01-5 OK MAX_DEPTH parameter is adjusted to match Adobe. - Alex - -31-01-6 OK Fixed - Alex - -31-01-7 OK Minor differences visually reviewed by RJJ - -31-01-8 DIFF Test 03 and 07 wrong. - The test defines 2 or more idioms that match the target and expects - the last definition to be used. PLRM (p. 121) says that the order is - undefined. assign Alex. - -31-01-9 DIFF same as 31-01-8 but in the global VM. assign Alex. - -31-02-1 OK Fixed in rev. 7473 - Alex - -31-02-2 OK - -31-03-1 OK Fixed in rev 7474. - Alex - -31-03-2 OK - -31-04-1 OK Minor differences in positions and character shapes - ADC - -31-04-2 OK Minor differences in positions and character shapes - ADC - -31-05-1 OK - -31-05-2 OK - -31-06-1 OK Fixed by gs_cet.ps - -31-06-2 OK Minor differences in positions and character shapes - ADC - -31-07-1 OK Minor differences visually reviewed by Igor. - Note: This test draws different length line depending on timing - (number of loops depends on 'realtime' resolution and results). - -31-07-2 OK - -31-08-1 OK Fixed by gs_cet.ps rev. 7180 (Device Dependent). - Note: CPSI shows revision 0, Tek shows revision 5. - -31-08-2 OK - -31-09-1 OK Fixed by gs_cet.ps rev. 7180 (Device Dependent). - Note: CPSI shows serialnumber 233460, Tek shows 1401788461 - -31-09-2 OK - -31-10-1 OK Minor differences in positions and character shapes - ADC - -31-10-2 OK Fixed in rev. 7749. - Alex - -31-10-3 OK - -31-11-1 OK Fixed in rev 7474. - Alex - -31-11-2 OK - -31-12-1 OK Minor differences visually reviewed by RJJ - Note: This test draws different length line depending on timing - (number of loops depends on 'realtime' resolution and results). - -31-12-2 OK - -31-13-1 OK - -31-13-2 OK Fixed as of rev 7583. - -32_all-1 AOK CPSI inserts CDevProc while /CIDFont defineresource. - That is not required by PLRM3. - Inserting a CDevProc is unnecessary and would impackt performance. - -32_all-10 OK - -32_all-11 OK - -32_all-12 OK - -32_all-13 OK - -32_all-14 OK Fixed as of rev 7583. - -32_all-15 AOK Same as 34_all-6 - -32_all-16 OK - -32_all-2 OK Fixed in rev. 7478. findfont, definefont, undefinefont also - handle /CIDFont resource instances now. - Alex - -32_all-3 OK - -32_all-4 OK - -32_all-5 OK - -32_all-6 OK - -32_all-7 OK - -32_all-8 OK - -32_all-9 OK - -33_all-1 OK Fixed as of rev 7583. - -33_all-2 OK Fixed as of rev 7583. - -33_all-3 OK Minor differences visually reviewed by RJJ - -33_all-4 OK - -33_all-5 OK - -33_all-6 OK Fixed as of rev 7583. - -33_all-7 AOK CMAP names differ implementation dependent analyzed by Ray. - -33_all-8 OK Minor differences visually reviewed by RJJ - -34_all-1 OK Fixed as of rev 7583. - -34_all-2 OK Fixed as of rev 7583. - -34_all-3 OK Fixed as of rev 7583. - -34_all-4 DIFF Improved by rev 7583, but still has mismatch for glyph 222. - Assign: Ray - -34_all-5 OK Fixed as of rev 7583. - -34_all-6 AOK GS has more CMap resources. Not important. Analyzed by Igor. - -34_all-7 OK Fixed as of rev 7583. - -35_all-1 DIFF Even as of rev 7583, CID Font has /CharStrings array. Tek - and CPSI do not have this key. Tek has CDevProc that CPSI does - not. Assign: Ray - -35_all-10 OK - -35_all-11 DIFF GS paints glyphs when CPSI and Tek paint hollow boxes. It appears that - GS is not removing glyphs from previous page "currentfont removeall". - Assign: Ray - -35_all-12 OK Fixed by rev. 7710 - Alex. - -35_all-2 OK Fixed as of rev 7583. - -35_all-3 OK Minor differences visually reviewed by RJJ - -35_all-4 OK - -35_all-5 OK - -35_all-6 OK Fixed as of rev 7711 (detected during regression testing. RJJ) - -35_all-7 AOK Same as 33_all-7. Analyzed by Igor. - -35_all-8 OK Minor differences visually reviewed by RJJ - -35_all-9 OK Minor differences visually reviewed by RJJ - -36-01-1 OK - -37-01-1 OK - -38-01-1 DIFF CPSI has more fonts, particularly more Type 42 fonts. - Analyzed by Igor. - This test prints some data about installed Type 42 fonts : - Chicago, Geneva, HoeflerText-Black, HoeflerText-BlackItalic, HoeflerText-Italic. - Neither URW nor UFST PCLPS2 provide them. - UFST PCLPS3 does provide. - Passing to Ray to decide what to do with it. - Assign: Ray. - -38-01-2 OK - -99-01-1 AOK Implementation Dependent: Different default system parameters can be set - if customer desires. - Environment dependent (GenericResourceDir). - -99-01-2 AOK Implementation Dependent: Different default device parameters can be set - if customer desires. - Environment dependent (OutputFile). - -99-01-3 OK - -99-02-1 OK GS OK visually reviewed by RJJ - cpsi/99-02-1 missing - Environment dependent (GenericResourceDir). - -99-03-1 OK - diff --git a/doc/sample_downscale_device.htm b/doc/sample_downscale_device.htm deleted file mode 100644 index eb28b9b5..00000000 --- a/doc/sample_downscale_device.htm +++ /dev/null @@ -1,235 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript: Sample CMYK 32-bit Device that Supports Post Rendering Processing</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Ghostscript: Sample CMYK 32-bit Device that Supports Post Rendering Processing</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Description">Description</a> - <li><a href="#Features">Features</a> - <li><a href="#devs_mak">Changes to devices/devs.mak</a> - <li><a href="#Building">Building Ghostscript with the driver</a> - <li><a href="#Source">Source code</a> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Drivers.htm">Ghostscript -device drivers</a> and the documentation on <a href="Make.htm">how to build -Ghostscript</a>. - -<!-- [1.3 end hint] ======================================================== --> - -<hr> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> - -<h2><a name="Description"></a>Description</h2> - -<p> -This device is a basic CMYK 32-bit (8-bits per component) device that uses the <code>downscaler</code> -features to provide post-rendering operations on the raster data produced by Ghostscript. -<p> -It is designed to allow a developer to add code to handle the resulting raster data -and perform any desired formatting and transmission to some destination, for example -DMA to a printer or sending over a network link. -<p> -<hr> - -<h2><a name="Features"></a>Features</h2> - -<p> -The <code>downscaler</code> modules provide for the following optional post-rendering -manipulation: - -<blockquote><dl> -<dt><code>-dDownScaleFactor=<em>factor</em></code> (small non-negative integer; default = 1) -<dd>If this option set then the page is downscaled by the given factor on both -axes. For example rendering with <tt>-r600</tt> and then specifying <tt>-dDownScaleFactor=3</tt> will produce -a 200dpi image. -<p> -2 additional "special" ratios are available, 32 and 34. 32 provides a 3:2 downscale -(so from 300 to 200 dpi, if the resolution is 300 dpi as with <code>-r300</code>). 34 produces a 3:4 upscale (so from 300 to 400 dpi, similarly). -</dl></blockquote> - -<blockquote><dl> -<dt><code>-sPostRenderProfile=<em>path</em></code> (path to an ICC profile) -<dd>If this option set then the page will be color transformed using that -profile <b>after</b> downscaling. -<p> -This is useful when the file uses overprint to separately paint to some -subset of the C, M, Y, and K colorants, but the final CMYK is to be color -corrected for printing or display. -</dl></blockquote> - -<p>The <code>ds32</code> device can perform rudimentary automatic bitmap -'trapping' on the final rendered bitmap. This code is disabled by default; see -the <a href="#trapping_patent_note">note</a> below as to why. - -<p>Trapping is a process whereby the output is adjusted to minimise the -visual impact of offsets between each printed plane. Typically this involves -slightly extending abutting regions that are rendered in different inks. The -intent of this is to avoid the unsightly gaps that might be otherwise be -revealed in the final printout if the different color plates do not exactly -line up. - -<p>This trapping is controlled by 3 device parameters. Firstly the maximum -X and Y offsets are specified using: -<blockquote><dl> -<dt><code>-dTrapX=N</code> -<dd>and -<dt> <code>-dTrapY=N</code> -<dd>(where <code>N</code> is a figure in pixels, <b>before</b> the downscaler is applied). -</dl></blockquote> - -<p>The final control is to inform the trapping process in what order inks -should be processed, from darkest to lightest. For a typical CMYK device -this order would be [ 3 1 0 2 ] (K darker than M darker than C darker than Y). -This is the default. - -<p>To override these defaults, the <code>TrapOrder</code> parameter can be used. Since -this parameter requires an array, it must be specified using a different method. For -example, if Cyan is darker than Magenta: - -<blockquote><code> - gs -sDEVICE=ds32 -dTrapX=2 -dTrapY=2 -c "<< /TrapOrder [ 3 0 1 2 ] >> setpagedevice" -f examples\colorcir.ps -</code></blockquote> - -<h4><a name="trapping_patent_note"></a>Trapping patents</h4> - -<p>Trapping is an technology area encumbered by many patents. Until -we can convince ourselves that our trapping code is not covered by -any of these patents, the functionality is disabled by default.</p> - -<p>It can be enabled by building with the <tt>ENABLE_TRAPPING</tt> -define, but before you do so you should convince yourself that -either:</p> - -<ul> -<li>The trapping code is not covered by any existing patent. -<li>Any patents that do cover the code are invalid in your -jurisdiction. -<li>That you have appropriate patent licenses for any patents - that do apply. -</ul> - -<p>You bear full responsibility for choosing to build with -<tt>ENABLE_TRAPPING</tt>. - -<p> - -<p> -<hr> - -<h2><a name="devs_mak"></a>Changes to devices/devs.mak</h2> - -<p> -The make files used to build Ghostscript use the file devices/devs.mak to -describe what is needed for devices that can be built into the executable, -such as source code files, header files, libraries and dependencies on -other parts of Ghostscript. -<p> -The section below can be added to the end of the devices/devs.mak file: - -<blockquote> -<pre> -### -------- Example 32-bit CMYK downscaled device --------------------- ### -# NB: downscale_ is standard in the lib (LIB1s) -$(DD)ds32.dev : $(DEVOBJ)gdevds32.$(OBJ) $(GLD)page.dev \ - $(GDEV) $(DEVS_MAK) $(MAKEDIRS) - $(SETPDEV2) $(DD)ds32 $(DEVOBJ)gdevds32.$(OBJ) - $(ADDMOD) $(DD)ds32 -include $(GLD)page - -$(DEVOBJ)gdevds32.$(OBJ) : $(DEVSRC)gdevds32.c $(gsicc_cache_h) $(gxdownscale_h) $(AK) \ - $(arch_h) $(gdevprn_h) $(stdio__h) $(stdint__h) $(DEVS_MAK) $(MAKEDIRS) - $(DEVCC) $(DEVO_)gdevds32.$(OBJ) $(C_) $(DEVSRC)gdevds32.c -</blockquote> - -This snippet is also in a commented block at the top of the source code file. -<p> -<hr> - -<h2><a name="Building"></a>Building Ghostscript with the driver</h2> - -<p> -The make system also needs to be told to include the <code>ds32</code> device. This can -either be added to the top level make file on one of the <code>DEVICE_DEVS</code> lines, -for example, in <code>psi/msvc.mak</code> for the Windows build: -<blockquote> -<pre> -DEVICE_DEVS21=$(DD)ds32.dev $(DD)spotcmyk.dev $(DD)devicen.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)cp50.dev $(DD)gprf.dev -</blockquote> - -Rather than editing a make file, there is a convenient macro that allows the extra device -to be added to the build command line, <code>DEVICE_DEVS_EXTRA</code>. For example, on -linux: -<blockquote> -<pre> -make DEVICE_DEVS_EXTRA=obj/ds32.dev -</blockquote> -or, on Windows: -<blockquote> -<pre> -nmake -f psi/msvc32.mak DEVICE_DEVS_EXTRA=obj\ds32.dev -</blockquote> -<hr> - -<h2><a name="Source"></a>Source code</h2> - -<p> -The source for this device driver is in: <a href="gdevds32.c">doc/gdevds32.c</a> - -<p> -<hr> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> - -<p> - <small>Copyright © 2016-2022 Artifex Software, Inc. All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/site.js b/doc/site.js deleted file mode 100644 index e805969f..00000000 --- a/doc/site.js +++ /dev/null @@ -1,14 +0,0 @@ -switch(window.location.protocol) { - case 'http:': - case 'https:': - // remote file - document.getElementById("searchSite").style.display = "block"; - break; - case 'file:': - // local file - document.getElementById("searchSite").style.display = "none"; - break; - default: - - break; -} diff --git a/doc/src/API.rst b/doc/src/API.rst new file mode 100644 index 00000000..d52338f5 --- /dev/null +++ b/doc/src/API.rst @@ -0,0 +1,1387 @@ +.. title:: API + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + + +.. _API.htm: + + +API +================================= + + + + + + +What is the Ghostscript Interpreter API? +------------------------------------------ + + +The Ghostscript interpreter can be built as a dynamic link library (DLL) on Microsoft Windows, as a shared object on the Linux, Unix and MacOS X platforms. With some changes, it could be built as a static library. This document describes the Application Programming Interface (API) for the Ghostscript interpreter library. This should not be confused with the :ref:`Ghostscript library<Lib.htm>` which provides a graphics library but not the interpreter. + +This supercedes the old DLL interface. + +To provide the interface described in the :ref:`usage documentation<Use.htm>`, a smaller independent executable loads the DLL/shared object. This executable must provide all the interaction with the windowing system, including image windows and, if necessary, a text window. + +The Ghostscript interpreter library's name and characteristics differ for each platform: + +- The Win32 DLL ``gsdll32.dll`` can be used by multiple programs simultaneously, but only once within each process. +- The OS/2 DLL ``gsdll2.dll`` has MULTIPLE NONSHARED data segments and can be called by multiple programs simultaneously. +- The Linux shared object ``libgs.so`` can be used by multiple programs simultaneously. + +The source for the executable is in ``dw*.*`` (Windows), ``dp*.*`` (OS/2) and ``dx*.*`` (Linux/Unix). See these source files for examples of how to use the DLL. + +The source file dxmainc.c can also serve as an example of how to use the shared library component on MacOS X, providing the same command-line tool it does on any linux, bsd or similar operating system. + +At this stage, Ghostscript does not support multiple instances of the interpreter within a single process. + + +.. _API.htm exported functions: +.. _gsapi_asterisk: + +Exported functions +------------------------------------------ + +The functions exported by the DLL/shared object are described in the header file ``iapi.h`` and are summarised below. Omitted from the summary are the calling convention (e.g. ``__stdcall``), details of return values and error handling. + + +.. role:: c(code) + :language: c + + +- :c:`int gsapi_revision (gsapi_revision_t *pr, int len);` :ref:`details<gsapi_revision>` +- :c:`int gsapi_new_instance (void **pinstance, void *caller_handle);` :ref:`details<gsapi_new_instance>` +- :c:`void gsapi_delete_instance (void *instance);` :ref:`details<gsapi_delete_instance>` +- :c:`int gsapi_set_stdio_with_handle (void *instance, int(*stdin_fn)(void *caller_handle, char *buf, int len), int(*stdout_fn)(void *caller_handle, const char *str, int len), int(*stderr_fn)(void *caller_handle, const char *str, int len), void *caller_handle);` :ref:`details<gsapi_set_stdio_with_handle>` +- :c:`int gsapi_set_stdio (void *instance, int(*stdin_fn)(void *caller_handle, char *buf, int len), int(*stdout_fn)(void *caller_handle, const char *str, int len), int(*stderr_fn)(void *caller_handle, const char *str, int len));` :ref:`details<gsapi_set_stdio>` +- :c:`int gsapi_set_poll_with_handle (void *instance, int(*poll_fn)(void *caller_handle), void *caller_handle);` :ref:`details<gsapi_set_poll_with_handle>` +- :c:`int gsapi_set_poll (void *instance, int(*poll_fn)(void *caller_handle));` :ref:`details<gsapi_set_poll>` +- :c:`int gsapi_set_display_callback (void *instance, display_callback *callback);` :ref:`details<gsapi_set_display_callback>` +- :c:`int gsapi_register_callout (void *instance, gs_callout callout, void *callout_handle);` :ref:`details<gsapi_register_callout>` +- :c:`void gsapi_deregister_callout (void *instance, gs_callout callout, void *callout_handle);` :ref:`details<gsapi_deregister_callout>` +- :c:`int gsapi_set_arg_encoding (void *instance, int encoding);` :ref:`details<gsapi_set_arg_encoding>` +- :c:`int gsapi_get_default_device_list(void *instance, char **list, int *listlen);` :ref:`details<gsapi_get_default_device_list>` +- :c:`int gsapi_set_default_device_list(void *instance, const char *list, int listlen);` :ref:`details<gsapi_set_default_device_list>` +- :c:`int gsapi_run_string_begin (void *instance, int user_errors, int *pexit_code);` :ref:`details<gsapi_run_asterisk>` +- :c:`int gsapi_run_string_continue (void *instance, const char *str, unsigned int length, int user_errors, int *pexit_code);` :ref:`details<gsapi_run_asterisk>` +- :c:`int gsapi_run_string_end (void *instance, int user_errors, int *pexit_code);` :ref:`details<gsapi_run_asterisk>` +- :c:`int gsapi_run_string_with_length (void *instance, const char *str, unsigned int length, int user_errors, int *pexit_code);` :ref:`details<gsapi_run_asterisk>` +- :c:`int gsapi_run_string (void *instance, const char *str, int user_errors, int *pexit_code);` :ref:`details<gsapi_run_asterisk>` +- :c:`int gsapi_run_file (void *instance, const char *file_name, int user_errors, int *pexit_code);` :ref:`details<gsapi_run_asterisk>` +- :c:`int gsapi_init_with_args (void *instance, int argc, char **argv);` :ref:`details<gsapi_init_with_args>` +- :c:`int gsapi_exit (void *instance);` :ref:`details<gsapi_exit>` +- :c:`int gsapi_set_param(void *instance, const char *param, const void *value, gs_set_param_type type);` :ref:`details<gsapi_set_param>` +- :c:`int gsapi_get_param(void *instance, const char *param, void *value, gs_set_param_type type);` :ref:`details<gsapi_get_param>` +- :c:`int gsapi_enumerate_params(void *instance, void **iter, const char **key, gs_set_param_type *type);` :ref:`details<gsapi_enumerate_params>` +- :c:`int gsapi_add_control_path(void *instance, int type, const char *path);` :ref:`details<gsapi_add_control_path>` +- :c:`int gsapi_remove_control_path(void *instance, int type, const char *path);` :ref:`details<gsapi_remove_control_path>` +- :c:`void gsapi_purge_control_paths(void *instance, int type);` :ref:`details<gsapi_purge_control_paths>` +- :c:`void gsapi_activate_path_control(void *instance, int enable);` :ref:`details<gsapi_activate_path_control>` +- :c:`int gsapi_is_path_control_active(void *instance);` :ref:`details<gsapi_is_path_control_active>` +- :c:`int gsapi_add_fs (void *instance, gsapi_fs_t *fs, void *secret);` :ref:`details<gsapi_add_fs>` +- :c:`void gsapi_remove_fs (void *instance, gsapi_fs_t *fs, void *secret);` :ref:`details<gsapi_remove_fs>` + + + + +.. _API.htm gsapi_revision: +.. _gsapi_revision: + + +gsapi_revision() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This function returns the revision numbers and strings of the Ghostscript interpreter library; you should call it before any other interpreter library functions to make sure that the correct version of the Ghostscript interpreter has been loaded. + + +.. code-block:: c + + typedef struct gsapi_revision_s { + const char *product; + const char *copyright; + long revision; + long revisiondate; + } gsapi_revision_t; + gsapi_revision_t r; + + if (gsapi_revision(&r, sizeof(r)) == 0) { + if (r.revision < 650) + printf("Need at least Ghostscript 6.50"); + } + else { + printf("revision structure size is incorrect"); + } + + +.. _API.htm gsapi_new_instance: +.. _gsapi_new_instance: + +gsapi_new_instance() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Create a new instance of Ghostscript. This instance is passed to most other gsapi functions. The caller_handle is the default value that will be provided to callback functions. On some platforms (those that do not support threading), only one instance of Ghostscript is supported at a time; any attempt to create more than one at a time would result in ``gsapi_new_instance`` returning an error. + +While the core Ghostscript devices are believed to be thread safe now, a handful of devices are known not to be (at least the :title:`x11` devices, :title:`uniprint`, and the open printing devices). A new mechanism has been implemented that allows devices to check for concurrent use and to refuse to start up. The devices shipped with Ghostscript known to use global variables have had these calls added to them. Any authors of non-standard Ghostscript devices that use global variables should consider adding the same calls to their own code. + +The first parameter, is a pointer to an opaque pointer (``void **``). The opaque pointer (``void *``) must be initialised to NULL before the call to ``gsapi_new_instance()``. See `Example 1`_. + +.. _API.htm gsapi_delete_instance: +.. _gsapi_delete_instance: + +gsapi_delete_instance() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Destroy an instance of Ghostscript. Before you call this, Ghostscript must have finished. If Ghostscript has been initialised, you must call ``gsapi_exit`` before ``gsapi_delete_instance``. + +.. _API.htm gsapi_set_stdio_with_handle: +.. _gsapi_set_stdio_with_handle: + +gsapi_set_stdio_with_handle() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback functions for stdio, together with the handle to use in the callback functions. The stdin callback function should return the number of characters read, 0 for EOF, or -1 for error. The stdout and stderr callback functions should return the number of characters written. + +NOTE: These callbacks do not affect output device I/O when using "%stdout" as the output file. In that case, device output will still be directed to the process "stdout" file descriptor, not to the stdio callback. + +.. _API.htm gsapi_set_stdio: +.. _gsapi_set_stdio: + +gsapi_set_stdio() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback functions for stdio. The handle used in the callbacks will be taken from the value passed to `gsapi_new_instance`_. Otherwise the behaviour of this function matches `gsapi_set_stdio_with_handle`_. + + +.. _API.htm gsapi_set_poll_with_handle: +.. _gsapi_set_poll_with_handle: + +gsapi_set_poll_with_handle() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback function for polling, together with the handle to pass to the callback function. This function will only be called if the Ghostscript interpreter was compiled with CHECK_INTERRUPTS as described in gpcheck.h. + +The polling function should return zero if all is well, and return negative if it wants Ghostscript to abort. This is often used for checking for a user cancel. This can also be used for handling window events or cooperative multitasking. + +The polling function is called very frequently during interpretation and rendering so it must be fast. If the function is slow, then using a counter to return 0 immediately some number of times can be used to reduce the performance impact. + + +.. _API.htm gsapi_set_poll: +.. _gsapi_set_poll: + +gsapi_set_poll() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback function for polling. The handle passed to the callback function will be taken from the handle passed to `gsapi_new_instance`_. Otherwise the behaviour of this function matches `gsapi_set_poll_with_handle`_. + + +.. _API.htm gsapi_set_display_callback: +.. _gsapi_set_display_callback: + +gsapi_set_display_callback() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +This call is deprecated; please use `gsapi_register_callout`_ to register a `callout`_ handler for the `display`_ device in preference. Set the callback structure for the display device. The handle passed in the callback functions is taken from the ``DisplayHandle`` parameter (or ``NULL`` if there is no such parameter). If the `display`_ device is used, this must be called after ``gsapi_new_instance()`` and before ``gsapi_init_with_args()``. See ``gdevdsp.h`` for more details. + + +.. _API.htm gsapi_register_callout: +.. _gsapi_register_callout: + +gsapi_register_callout() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call registers a `callout`_ handler. + + + +.. _API.htm gsapi_deregister_callout: +.. _gsapi_deregister_callout: + +gsapi_deregister_callout() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call deregisters a `callout`_ handler previously registered with `gsapi_register_callout`_. All three arguments must match exactly for the callout handler to be deregistered. + + +.. _API.htm gsapi_set_arg_encoding: +.. _gsapi_set_arg_encoding: + +gsapi_set_arg_encoding() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the encoding used for the interpretation of all subsequent args supplied via the gsapi interface on this instance. By default we expect args to be in encoding 0 (the 'local' encoding for this OS). On Windows this means "the currently selected codepage". On Linux this typically means utf8. This means that omitting to call this function will leave Ghostscript running exactly as it always has. Please note that use of the 'local' encoding is now deprecated and should be avoided in new code. This must be called after ``gsapi_new_instance()`` and before ``gsapi_init_with_args()``. + + +.. _API.htm gsapi_set_default_device_list: +.. _gsapi_set_default_device_list: + +gsapi_set_default_device_list() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the string containing the list of default device names, for example "display x11alpha x11 bbox". Allows the calling application to influence which device(s) gs will try, in order, in it's selection of the default device. This must be called after ``gsapi_new_instance()`` and before ``gsapi_init_with_args()``. + + +.. _API.htm gsapi_get_default_device_list: +.. _gsapi_get_default_device_list: + + +gsapi_get_default_device_list() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Returns a pointer to the current default device string. This must be called after ``gsapi_new_instance()`` and before ``gsapi_init_with_args()``. + +.. _API.htm gsapi_init_with_args: +.. _gsapi_init_with_args: + + +gsapi_init_with_args() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Initialise the interpreter. This calls ``gs_main_init_with_args()`` in ``imainarg.c`` . See below for `return codes`_. The arguments are the same as the "C" main function: ``argv[0]`` is ignored and the user supplied arguments are ``argv[1]`` to ``argv[argc-1]``. + + +.. _API.htm gsapi_run_asterisk: +.. _gsapi_run_asterisk: + + +gsapi_run_*() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``gsapi_run_*`` functions are like ``gs_main_run_*`` except that the error_object is omitted. If these functions return <= -100, either quit or a fatal error has occured. You must call ``gsapi_exit()`` next. The only exception is ``gsapi_run_string_continue()`` which will return ``gs_error_NeedInput`` if all is well. See below for `return codes`_. + +The address passed in ``pexit_code`` will be used to return the exit code for the interpreter in case of a quit or fatal error. The ``user_errors`` argument is normally set to zero to indicate that errors should be handled through the normal mechanisms within the interpreted code. If set to a negative value, the functions will return an error code directly to the caller, bypassing the interpreted language. The interpreted language's error handler is bypassed, regardless of ``user_errors`` parameter, for the ``gs_error_interrupt`` generated when the polling callback returns a negative value. A positive ``user_errors`` is treated the same as zero. + +There is a 64 KB length limit on any buffer submitted to a ``gsapi_run_*`` function for processing. If you have more than 65535 bytes of input then you must split it into smaller pieces and submit each in a separate ``gsapi_run_string_continue()`` call. + + +.. _API.htm gsapi_exit: +.. _gsapi_exit: + + +gsapi_exit() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Exit the interpreter. This must be called on shutdown if ``gsapi_init_with_args()`` has been called, and just before ``gsapi_delete_instance()``. + + +.. _API.htm gsapi_set_param: +.. _gsapi_set_param: + + +gsapi_set_param() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set a parameter. Broadly, this is equivalent to setting a parameter using ``-d``, ``-s`` or ``-p`` on the command line. This call cannot be made during a ``run_string`` operation. +Parameters in this context are not the same as 'arguments' as processed by ``gsapi_init_with_args``, but often the same thing can be achieved. For example, with ``gsapi_init_with_args``, we can pass "-r200" to change the resolution. Broadly the same thing can be achieved by using ``gsapi_set_param`` to set a parsed value of "<</HWResolution [ 200.0 200.0 ]>>". + +Note, that internally, when we set a parameter, we perform an ``initgraphics`` operation. This means that using ``set_param`` other than at the start of a page is likely to give unexpected results. + +Further, note that attempting to set a parameter that the device does not recognise will be silently ignored, and that parameter will not be found in subsequent ``gsapi_get_param`` calls. + +The ``type`` argument dictates the kind of object that ``value`` points to: + + +.. code-block:: c + + typedef enum { + gs_spt_invalid = -1, + gs_spt_null = 0, /* void * is NULL */ + gs_spt_bool = 1, /* void * is a pointer to an int (0 false, + * non-zero true). */ + gs_spt_int = 2, /* void * is a pointer to an int */ + gs_spt_float = 3, /* void * is a float * */ + gs_spt_name = 4, /* void * is a char * */ + gs_spt_string = 5, /* void * is a char * */ + gs_spt_long = 6, /* void * is a long * */ + gs_spt_i64 = 7, /* void * is an int64_t * */ + gs_spt_size_t = 8, /* void * is a size_t * */ + gs_spt_parsed = 9, /* void * is a pointer to a char * to be parsed */ + + /* Setting a typed param causes it to be instantly fed to to the + * device. This can cause the device to reinitialise itself. Hence, + * setting a sequence of typed params can cause the device to reset + * itself several times. Accordingly, if you OR the type with + * gs_spt_more_to_come, the param will held ready to be passed into + * the device, and will only actually be sent when the next typed + * param is set without this flag (or on device init). Not valid + * for get_typed_param. */ + gs_spt_more_to_come = 1<<31 + } gs_set_param_type; + + +Combining a type value by ORRing it with the ``gs_spt_more_to_come`` flag will cause the set_param operation to be queued internally, but not actually be sent to the device. Thus a series of ``set_param`` operations can be queued, for example as below: + + +.. code-block:: c + + int code = gsapi_set_param(instance, + "HWResolution", + "[300 300]", + gs_spt_parsed | gs_spt_more_to_come); + if (code >= 0) { + int i = 1; + code = gsapi_set_param(instance, + "FirstPage", + &i, + gs_spt_int | gs_spt_more_to_come); + } + if (code >= 0) { + int i = 3; + code = gsapi_set_param(instance, + "DownScaleFactor", + &i, + gs_spt_int); + } + + +This enables a series of set operations to be performed 'atomically'. This can be useful for performance, in that any reconfigurations to the device (such as page size changes or memory reallocations) will only happen when all the parameters are sent, rather than potentially each time each one is sent. + + +.. _API.htm gsapi_get_param: +.. _API_gsapi_get_param: +.. _gsapi_get_param: + + +gsapi_get_param() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Get a parameter. Retrieve the current value of a parameter. + +If an error occurs, the return value is negative. Otherwise the return value is the number of bytes required for storage of the value. Call once with ``value = NULL`` to get the number of bytes required, then call again with ``value`` pointing to at least the required number of bytes where the value will be copied out. Note that the caller is required to know the type of value in order to get it. For all types other than ``string``, ``name``, and ``parsed`` knowing the type means you already know the size required. + +This call retrieves parameters/values that have made it to the device. Thus, any values set using the ``gs_spt_more_to_come`` without a following call without that flag will not be retrieved. Similarly, attempting to get a parameter before ``gsapi_init_with_args`` has been called will not list any, even if ``gsapi_set_param`` has been used. + +Attempting to read a parameter that is not set will return ``gs_error_undefined (-21)``. Note that calling ``gsapi_set_param`` followed by ``gsapi_get_param`` may not find the value, if the device did not recognise the key as being one of its configuration keys. + + +.. _API.htm gsapi_enumerate_params: +.. _gsapi_enumerate_params: + + +gsapi_enumerate_params() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enumerate the current parameters. Call repeatedly to list out the current parameters. + +The first call should have ``*iter = NULL``. Subsequent calls should pass the same pointer in so the iterator can be updated. Negative return codes indicate error, 0 success, and 1 indicates that there are no more keys to read. On success, key will be updated to point to a null terminated string with the key name that is guaranteed to be valid until the next call to ``gsapi_enumerate_params``. If ``type`` is non ``NULL`` then ``*type`` will be updated to have the type of the parameter. + +Note that only one enumeration can happen at a time. Starting a second enumeration will reset the first. + +The enumeration only returns parameters/values that have made it to the device. Thus, any values set using the ``gs_spt_more_to_come`` without a following call without that flag will not be retrieved. Similarly, attempting to enumerate parameters before ``gsapi_init_with_args`` has been called will not list any, even if ``gsapi_set_param`` has been used. + + +.. _API.htm gsapi_add_control_path: +.. _gsapi_add_control_path: + +gsapi_add_control_path() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add a (case sensitive) path to one of the lists of permitted paths for file access. See :ref:`dSAFER<Use Safer>` for more information about permitted paths. + +.. _API.htm gsapi_remove_control_path: +.. _gsapi_remove_control_path: + +gsapi_remove_control_path() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remove a (case sensitive) path from one of the lists of permitted paths for file access. See :ref:`dSAFER<Use Safer>` for more information about permitted paths. + + +.. _API.htm gsapi_purge_control_paths: +.. _gsapi_purge_control_paths: + +gsapi_purge_control_paths() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Clear all the paths from one of the lists of permitted paths for file access. See :ref:`dSAFER<Use Safer>` for more information about permitted paths. + + +.. _API.htm gsapi_activate_path_control: +.. _gsapi_activate_path_control: + +gsapi_activate_path_control() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Enable/Disable path control (i.e. whether paths are checked against permitted paths before access is granted). See :ref:`dSAFER<Use Safer>` for more information about permitted paths. + + +.. _API.htm gsapi_is_path_control_active: +.. _gsapi_is_path_control_active: + +gsapi_is_path_control_active() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Query whether path control is activated or not. See :ref:`dSAFER<Use Safer>` for more information about permitted paths. + + +.. _API.htm gsapi_add_fs: + +gsapi_add_fs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adds a new 'Filing System' to the interpreter. This enables callers to implement their own filing systems. The system starts with just the conventional 'file' handlers installed, to allow access to the local filing system. Whenever files are to be opened from the interpreter, the file paths are offered around each registered filing system in turn (from most recently registered to oldest), until either an error is given, or the file is opened successfully. + +Details of the ``gsapi_fs_t`` are given :ref:`below <gsapi_fs_t>`. + + +.. _API.htm gsapi_remove_fs: + +gsapi_remove_fs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Remove a previously registered 'Filing System' from the interpreter. Both the function pointers within the ``gs_fs_t`` and the secret value must match exactly. + + + +.. _API.htm gsapi_fs_t: + +gsapi_fs_t +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Each 'filing system' within ``gs`` is a structure of function pointers; each function pointer gives a handler from taking a different named resource (a file, a pipe, a printer, a scratch file etc) and attempts to open it. + + +.. code-block:: c + + typedef struct + { + int (*open_file)(const gs_memory_t *mem, + void *secret, + const char *fname, + const char *mode, + gp_file **file); + int (*open_pipe)(const gs_memory_t *mem, + void *secret, + const char *fname, + char *rfname, /* 4096 bytes */ + const char *mode, + gp_file **file); + int (*open_scratch)(const gs_memory_t *mem, + void *secret, + const char *prefix, + char *rfname, /* 4096 bytes */ + const char *mode, + int rm, + gp_file **file); + int (*open_printer)(const gs_memory_t *mem, + void *secret, + char *fname, /* 4096 bytes */ + int binary, + gp_file **file); + int (*open_handle)(const gs_memory_t *mem, + void *secret, + char *fname, /* 4096 bytes */ + const char *mode, + gp_file **file); + } gsapi_fs_t; + + +If the filename (always given in utf-8 format) is recognised as being one that the filing system handles (perhaps by the prefix used), then it should open the file, fill in the ``gp_file`` pointer and return 0. + +If the filename is not-recognised as being one that the filing system handles, then returning 0 will cause the filename to be offered to other registered filing systems. + +If an error is returned (perhaps ``gs_error_invalidfileaccess``), then no other filing system will be allowed to try to open the file. This provides a mechanism whereby a caller to gsapi can completely control access to all files accessed via ``gp_fopen`` at runtime. + +Note, that while most file access within Ghostscript will be redirected via these functions, stdio will not; see the existing mechanisms within Ghostscript for intercepting/replacing this. + +- The ``open_file`` function pointer will be called when something (most often a call to ``gp_fopen``) attempts to open a file. + +- The ``open_pipe`` function pointer will be called when something (most often a call to ``gp_popen``) attempts to open a pipe. ``rfname`` points to a 4K buffer in which the actual name of the opened pipe should be returned. + +- The ``open_scratch`` function pointer will be called when something (most often a call to ``gp_open_scratch_file`` or ``gp_open_scratch_file_rm``) attempts to open a temporary file. rfname points to a 4K buffer in which the actual name of the opened pipe should be returned. If ``rm`` is true, then the file should be set to delete itself when all handles to it are closed. + +- The ``open_printer`` function pointer will be called when something (most often a call to ``gp_open_printer``) attempts to open a stream to a printer. If ``binary`` is true, then the stream should be opened as binary; most streams will be binary by default - this has historical meaning on OS/2. + +- The ``open_handle`` function pointer will be called when something (most often a call via the postscript %handle% IO device) attempts to open a Windows handle. This entry point will never be called on non-Windows builds. + +Any of these which are left as ``NULL`` will never be called; a filing system with all of the entries left as ``NULL`` is therefore pointless. + +The most complex part of the implementation of these functions is the creation of a ``gp_file`` instance to return. There are some helper functions for this, best explained by example. + +Let us consider a hypothetical filing system that encrypts data as it is written, and decrypts it as it is read back. As each file is read and written the encryption/decryption routines will need to use some state, carried between calls to the filing system. We therefore might define a new type 'derived' from ``gp_file`` as follows: + + +.. code-block:: c + + typedef struct + { + gp_file base; + /* State private to the implementation of this file for encryption/decryption */ + /* For example: */ + int foo; + char *bar; + } gp_file_crypt; + +An implementation of ``gs_fs_t`` for our 'crypt' filing system might then look like this: + + +.. code-block:: c + + gsapi_fs_t gs_fs_crypt = + { + crypt_open_file, + NULL, /* open_pipe */ + NULL, /* open_scratch */ + NULL, /* open_printer */ + NULL /* open_handle */ + }; + + +In the above definition, we define a single handler, to cope with the opening of our input/output files. If we wanted to encrypt/decrypt other files too (perhaps the temporary files we produce) we'd need to define additional handlers (such as ``open_scratch``). + +Our handler might look as follows: + + +.. code-block:: c + + int crypt_open_file(const gs_memory_t *mem, + void *secret, + const char *filename, + const char *mode, + gp_file **file) + { + gp_file_crypt crypt; + + /* Ignore any filename not starting with "crypt://" */ + if (strncmp(filename, "crypt://", 8) != 0) + return 0; + + /* Allocate us an instance (and fill in the non-crypt-specific + * internals) */ + crypt = (gp_file_crypt *)gp_file_alloc(mem, &crypt_ops, sizeof(*crypt), "gp_file_crypt"); + if (crypt == NULL) + return gs_error_VMerror; /* Allocation failed */ + + /* Setup the crypt-specific state */ + crypt->foo = 1; + crypt->bar = gs_alloc_bytes(mem->non_gc_memory, 256, "bar"); + /* If allocations fail, we need to clean up before exiting */ + if (crypt->bar) { + gp_file_dealloc(crypt); + return gs_error_VMerror; + } + + /* Return the new instance */ + *file = &crypt.base; + return 0; + } + + +The crucial part of this function is the definition of ``crypt_ops``, an instance of the ``gp_file_ops_t`` type; a table of function pointers that implement the actual operations required. + +.. code-block:: c + + typedef struct { + int (*close)(gp_file *); + int (*getc)(gp_file *); + int (*putc)(gp_file *, int); + int (*read)(gp_file *, size_t size, unsigned int count, void *buf); + int (*write)(gp_file *, size_t size, unsigned int count, const void *buf); + int (*seek)(gp_file *, gs_offset_t offset, int whence); + gs_offset_t (*tell)(gp_file *); + int (*eof)(gp_file *); + gp_file *(*dup)(gp_file *, const char *mode); + int (*seekable)(gp_file *); + int (*pread)(gp_file *, size_t count, gs_offset_t offset, void *buf); + int (*pwrite)(gp_file *, size_t count, gs_offset_t offset, const void *buf); + int (*is_char_buffered)(gp_file *file); + void (*fflush)(gp_file *file); + int (*ferror)(gp_file *file); + FILE *(*get_file)(gp_file *file); + void (*clearerr)(gp_file *file); + gp_file *(*reopen)(gp_file *f, const char *fname, const char *mode); + } gp_file_ops_t; + + +These functions generally follow the same patterns as the posix functions that match them, and so in many cases we will describe these with references to such. Whenever these routines are called, they will be passed a ``gp_file`` pointer. This pointer will have originated from the ``crypt_open_file`` call, and so can safely be cast back to a ``gp_file_crypt`` pointer to allow private data to be accessed. + + + + + :c:`close(gp_file *)` + - close the given file; free any storage in the crypt specific parts of ``gp_file_crypt``, but not the ``gp_file_crypt`` structure itself. + + :c:`int getc(gp_file *)` + - Get a single character from the file, returning it as an int (or -1 for EOF). Behaves like ``fgetc(FILE *)``. + + :c:`int putc(gp_file *, int)` + - Put a single character to the file, returning the character on success, or EOF (and setting the error indicator) on error. Behaves like ``fgetc(FILE *)``. + + :c:`int read(gp_file *, size_t size, unsigned int count, void *buf)` + - Reads count entries of size bytes the file into ``buf``, returning the number of entries read. Behaves like ``fread(FILE *, size, count, buf)``. + + :c:`int write(gp_file *, size_t size, unsigned int count, const void *buf)` + - Writes count entries of size bytes from ``buf`` into the file, returning the number of entries written. Behaves like ``fwrite(FILE *, size, count, buf)``. + + :c:`int seek(gp_file *, gs_offset_t offset, int whence)` + - Seeks within the file. Behaves like ``fseek(FILE *, offset, whence)``. + + :c:`gs_offset_t tell(gp_file *)` + - Returns the current offset within the file. Behaves like ``ftell(FILE *)``. + + :c:`int eof(gp_file *)` + - Returns 1 if we are at the end of the file, 0 otherwise. Behaves like ``feof(FILE *)``. + + :c:`gp_file * dup(gp_file *, const char *mode)` + - Optional function, only used if clist files are to be stored in this filing system. Behaves like ``fdup(FILE *)``. Leave ``NULL`` if not implemented. + + :c:`int seekable(gp_file *)` + - Returns 1 if the file is seekable, 0 otherwise. Certain output devices will only work with seekable files. + + :c:`int pread(gp_file *, size_t count, gs_offset_t offset, void *buf)` + - Optional function, only used if clist files are to be stored in this filing system. Behaves like an atomic ``fseek(FILE *, offset, 0)`` and ``fread(FILE *, 1, count, buf)``. Akin to ``pread``. + + :c:`int pwrite(gp_file *, size_t count, gs_offset_t offset, const void *buf)` + - Optional function, only used if clist files are to be stored in this filing system. Behaves like an atomic ``fseek(FILE *, offset, 0)`` and ``fwrite(FILE *, 1, count, buf)``. Akin to ``pwrite``. + + :c:`int is_char_buffered(gp_file *file)` + - Returns 1 if the file is character buffered, 0 otherwise. Used for handling reading from terminals. Very unlikely to be used, so returning 0 all the time should be safe. Leave ``NULL`` to indicate "always 0". + + :c:`void fflush(gp_file *file)` + - Ensures that any buffered data is written to the file. Behaves like ``fflush(FILE *)``. Leave ``NULL`` to indicate that no flushing is ever required. + + :c:`int ferror(gp_file *file)` + - Returns non-zero if there has been an error, or 0 otherwise. Behaves like ``ferror(FILE *)``. + + :c:`FILE * get_file(gp_file *file)` + - Optional: Gets the ``FILE *`` pointer that backs this file. Required for a few devices that insist on working with ``FILE *``'s direct. Generally safe to leave this set to ``NULL``, and those devices will fail gracefully. + + :c:`void clearerr(gp_file *file)` + - Clear the error and EOF values for a file. Behaves like ``clearerror(FILE *)``. + + :c:`gp_file * reopen(gp_file *f, const char *fname, const char *mode)` + - Optional function, only used if the ``gp_file`` came from an ``open_scratch`` call; can be left as ``NULL`` if the ``open_scratch`` pointer is set to ``NULL``. Reopen a stream with a different mode. Behaves like ``freopen(fname, mode, FILE *)``. + + + + + + + +.. _callout: + + +Callouts +------------------------------------------ + +Callouts are a mechanism for the core code (specifically devices) to communicate with the user of gsapi. This communication can take the form of passing information out vis-a-vis what devices are doing, or requesting configuration from the caller to affect exactly how the device itself works. + +This is deliberately an extensible system, so exact details of callouts should be documented with the device in question. In general however a callout handler will be of the form: + + +.. code-block:: c + + typedef int (*gs_callout)(void *callout_handle, + const char *device_name, + int id, + int size, + void *data); + + +The ``callout_handle`` value passed to the callout will be the value passed in at registration. The device_name should be a null-terminated string giving the name of the device (though care should be taken to cope with the case where ``device_name`` is ``NULL`` for potential future uses). The id value will have a (device-specific) meaning; see the documentation for the device in question for more details. The same id value may be used to mean different things in different devices. Finally, size and data have callout specific meanings, but typically, data will be a pointer to data block (which may either be uninitialised or wholly/partially initialised on entry, and may be updated on exit), and size will be the size (in bytes) of the block pointed to by data. + +A return value of -1 (``gs_error_unknownerror``) means the callout was not recognised by the handler, and should be passed to more handlers. Other negative values are interpreted as standard Ghostscript error values, and stop the propagation of the callout. Non-negative return codes mean the callout was handled and should not be passed to any more registered callout handlers. + + + +.. _API_Return codes: + + +Return codes +-------------- + + +The gsapi_init_with_args_, :ref:`gsapi_run_*<gsapi_run_asterisk>` and gsapi_exit_ functions return an integer code. + + +Return Codes from ``gsapi_*()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - CODE + - STATUS + * - 0 + - No errors + * - gs_error_Quit + - "quit" has been executed. This is not an error. ```gsapi_exit()`` must be called next. + * - gs_error_interrupt + - The polling callback function returned a negative value, requesting Ghostscript to abort. + * - gs_error_NeedInput + - More input is needed by ``gsapi_run_string_continue()``. This is not an error. + * - gs_error_Info + - "gs -h" has been executed. This is not an error. ``gsapi_exit()`` must be called next. + * - < 0 + - Error + * - <= gs_error_Fatal + - Fatal error. ``gsapi_exit()`` must be called next. + + +The ``gsapi_run_*()`` functions do not flush stdio. If you want to see output from Ghostscript you must do this explicitly as shown in the example below. + +When executing a string with ``gsapi_run_string_*()``, ``currentfile`` is the input from the string. Reading from ``%stdin`` uses the stdin callback. + + +Example Usage +-------------- + + +To try out the following examples in a development environment like Microsoft's developer tools or Metrowerks Codewarrior, create a new project, save the example source code as a ``.c`` file and add it, along with the Ghostscript dll or shared library. You will also need to make sure the Ghostscript headers are available, either by adding their location (the src directory in the Ghostscript source distribution) to the project's search path, or by copying ``ierrors.h`` and ``iapi.h`` into the same directory as the example source. + + + +Example 1 +~~~~~~~~~~~~~~~ + +.. code-block:: c + + /* Example of using GS DLL as a ps2pdf converter. */ + + #if defined(_WIN32) && !defined(_Windows) + # define _Windows + #endif + #ifdef _Windows + /* add this source to a project with gsdll32.dll, or compile it directly with: + * cl -D_Windows -Isrc -Febin\ps2pdf.exe ps2pdf.c bin\gsdll32.lib + */ + # include <windows.h> + # define GSDLLEXPORT __declspec(dllimport) + #endif + + #include "ierrors.h" + #include "iapi.h" + + void *minst = NULL; + + int main(int argc, char *argv[]) + { + int code, code1; + const char * gsargv[7]; + int gsargc; + gsargv[0] = ""; + gsargv[1] = "-dNOPAUSE"; + gsargv[2] = "-dBATCH"; + gsargv[3] = "-dSAFER"; + gsargv[4] = "-sDEVICE=pdfwrite"; + gsargv[5] = "-sOutputFile=out.pdf"; + gsargv[6] = "input.ps"; + gsargc=7; + + code = gsapi_new_instance(&minst, NULL); + if (code < 0) + return 1; + code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); + if (code == 0) + code = gsapi_init_with_args(minst, gsargc, gsargv); + code1 = gsapi_exit(minst); + if ((code == 0) || (code == gs_error_Quit)) + code = code1; + + gsapi_delete_instance(minst); + + if ((code == 0) || (code == gs_error_Quit)) + return 0; + return 1; + } + + +Example 2 +~~~~~~~~~~~~~~~ + +.. code-block:: c + + /* Similar to command line gs */ + + #if defined(_WIN32) && !defined(_Windows) + # define _Windows + #endif + #ifdef _Windows + /* Compile directly with: + * cl -D_Windows -Isrc -Febin\gstest.exe gstest.c bin\gsdll32.lib + */ + # include <windows.h> + # define GSDLLEXPORT __declspec(dllimport) + #endif + #include <stdio.h> + #include "ierrors.h" + #include "iapi.h" + + /* stdio functions */ + static int GSDLLCALL + gsdll_stdin(void *instance, char *buf, int len) + { + int ch; + int count = 0; + while (count < len) { + ch = fgetc(stdin); + if (ch == EOF) + return 0; + *buf++ = ch; + count++; + if (ch == '\n') + break; + } + return count; + } + + static int GSDLLCALL + gsdll_stdout(void *instance, const char *str, int len) + { + fwrite(str, 1, len, stdout); + fflush(stdout); + return len; + } + + static int GSDLLCALL + gsdll_stderr(void *instance, const char *str, int len) + { + fwrite(str, 1, len, stderr); + fflush(stderr); + return len; + } + + void *minst = NULL; + const char start_string[] = "systemdict /start get exec\n"; + + int main(int argc, char *argv[]) + { + int code, code1; + int exit_code; + + code = gsapi_new_instance(&minst, NULL); + if (code < 0) + return 1; + gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr); + code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); + if (code == 0) + code = gsapi_init_with_args(minst, argc, argv); + if (code == 0) + code = gsapi_run_string(minst, start_string, 0, &exit_code); + code1 = gsapi_exit(minst); + if ((code == 0) || (code == gs_error_Quit)) + code = code1; + + gsapi_delete_instance(minst); + + if ((code == 0) || (code == gs_error_Quit)) + return 0; + return 1; + } + + +Example 3 +~~~~~~~~~~~~~~~ + + +Replace ``main()`` in either of the above with the following code, showing how you can feed Ghostscript piecemeal: + + +.. code-block:: c + + const char *command = "1 2 add == flush\n"; + + int main(int argc, char *argv[]) + { + int code, code1; + int exit_code; + + code = gsapi_new_instance(&minst, NULL); + if (code < 0) + return 1; + code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8); + if (code == 0) + code = gsapi_init_with_args(minst, argc, argv); + + if (code == 0) { + gsapi_run_string_begin(minst, 0, &exit_code); + gsapi_run_string_continue(minst, command, strlen(command), 0, &exit_code); + gsapi_run_string_continue(minst, "qu", 2, 0, &exit_code); + gsapi_run_string_continue(minst, "it", 2, 0, &exit_code); + gsapi_run_string_end(minst, 0, &exit_code); + } + + code1 = gsapi_exit(minst); + if ((code == 0) || (code == gs_error_Quit)) + code = code1; + + gsapi_delete_instance(minst); + + if ((code == 0) || (code == gs_error_Quit)) + return 0; + return 1; + } + + +Example 4 +~~~~~~~~~~~~~~~ + +When feeding Ghostscript piecemeal buffers, one can use the normal operators to configure things and invoke library routines. For example, to parse a PDF file one could say: + + +.. code-block:: c + + code = gsapi_run_string(minst, "(example.pdf) .runlibfile", 0, &exit_code); + +and Ghostscript would open and process the file named "example.pdf" as if it had been passed as an argument to ``gsapi_init_with_args()``. + + + + +Multiple Threads +-------------------- + +The Ghostscript library should have been compiled with a thread safe run time library. Synchronisation of threads is entirely up to the caller. The exported ``gsapi_*()`` functions must be called from one thread only. + + + +Standard Input and Output +---------------------------------------- + +When using the Ghostscript interpreter library interface, you have a choice of two standard input/output methods. + +- If you do nothing, the "C" stdio will be used. + +- If you use ``gsapi_set_stdio()``, all stdio will be redirected to the callback functions you provide. This would be used in a graphical user interface environment where stdio is not available, or where you wish to process Ghostscript input or output. + +The callback functions are described in ``iapi.h``. + + + +.. _display: + +Display Device +----------------- + +The display device is available for use with the Ghostscript interpreter library. While originally designed for allowing screen display of rendered output from Ghostscript, this is now powerful enough to provide a simple mechanism for getting rendered output suitable for use in all manner of output scenarios, including printing. + +Details of the API and options are given in the file ``gdevdsp.h``. This device provides you with access to the raster output of Ghostscript. It is the callers responsibility to copy this raster to a display window or printer. + +In order for this device to operate, it needs access to a structure containing a set of callback functions, and a callback handle (an opaque ``void *`` that can be used by caller to locate its own state). There are 2 ways that the device can get this information, a legacy method, and a modern method. + + +Legacy method +~~~~~~~~~~~~~~~~ + +The address of the callback structure, is provided using ``gsapi_set_display_callback()``. This must be called after ``gsapi_new_instance()`` and before ``gsapi_init_with_args()``. + +With this call, the callback handle is passed as ``NULL`` by default, but can be overridden by using a parameter. We actively dislike this way of working, as we consider passing addresses via the command line distasteful. The handle can be set using: + + +.. code-block:: bash + + -sDisplayHandle=1234 + +Where "1234" is a string. The API was changed to use a string rather than an integer/long value when support for 64 bit systems arrived. A display "handle" is often a pointer, and since these command line options have to survive being processed by Postscript machinery, and Postscript only permits 32 bit number values, a different representation was required. Hence changing the value to a string, so that 64 bit values can be supported. The string formats allowed are: + + + +.. list-table:: + :widths: 50 50 + + * - 1234 + - implicit base 10 + * - 10#1234 + - explicit base 10 + * - 16#04d2 + - explicit base 16 + +The "number string" is parsed by the display device to retrieve the number value, and is then assigned to the void pointer parameter "pHandle" in the display device structure. Thus, for a trivial example, passing ``-sDisplayHandle=0`` will result in the first parameter passed to your display device callbacks being: ``(void *)0``. + +The previous API, using a number value: + +.. code-block:: bash + + -dDisplayHandle=1234 + +is still supported on 32 bit systems, but will cause a "typecheck" error on 64 bit systems, and is considered deprecated. It should not be used in new code. + + + +Modern method +~~~~~~~~~~~~~~~~ + + +The preferred method is to register a callout handler using gsapi_register_callout_. When this handler is called for the "display" device, with ``id = 0 (= DISPLAY_CALLOUT_GET_CALLBACK)``, then data should point to an empty ``gs_display_get_callback_t`` block, with ``size = sizeof(gs_display_get_callback_t)``. + + +.. code-block:: c + + typedef struct { + display_callback *callback; + void *caller_handle; + } gs_display_get_callback_t; + + +The handler should fill in the structure before returning, with a return code of 0. + +Note, that the ``DisplayHandle`` value is only consulted for display device callbacks registered using the (legacy, now deprecated) ``gsapi_set_display_callback`` API, not the preferred ``gsapi_register_callout`` based mechanism. + +The device raster format can be configured using: + + +.. code-block:: bash + + -dDisplayFormat=NNNN + + +Options include: + +- native, gray, RGB, CMYK or separation color spaces. +- alpha byte (ignored). +- 1 to 16 bits/component. +- bigendian (RGB) or littleendian (BGR) order. +- top first or bottom first raster. +- 16 bits/pixel with 555 or 565 bitfields. +- Chunky, Planar and Planar interleaved formats. +- "Full screen" or "Rectangle Request" modes of operation. + +The operation of the device is best described with a walkthrough of some example code that uses it. For simplicity and clarity, we have omitted the error handling code in this example; in production code, every place where we get a code value returned we should check it for failure (a negative value) and clean up accordingly. First, we create an instance of Ghostscript: + + +.. code-block:: c + + void *minst = NULL; + code = gsapi_new_instance(&minst, NULL); + code = gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr); + +Next, we have to give the display device the address of our callback structure. In old code, we would do so using something like this: + +.. code-block:: c + + code = gsapi_set_display_callback(minst, &display_callback); + +We strongly recommend that you don't do that, but instead use the more modern :ref:`callout<Modern method>` mechanism: + + +.. code-block:: c + + code = gsapi_register_callout(minst, my_callout_handler, state); + +where ``state`` is any ``void *`` value you like, usually a pointer to help you reach any internal state you may need. Earlier in your code you would have the definition of ``my_callout_handler`` that might look like this: + + +.. code-block:: c + + static int + my_callout_handler(void *instance, + void *callout_handle, + const char *device_name, + int id, + int size, + void *data) + { + /* On entry, callout_handle == the value of state passed in + * to gsapi_register_callout. */ + /* We are only interested in callouts from the display device. */ + if (device_name == NULL || strcmp(device_name, "display")) + return -1; + + if (id == DISPLAY_CALLOUT_GET_CALLBACK) + { + /* Fill in the supplied block with the details of our callback + * handler, and the handle to use. In this instance, the handle + * is the pointer to our test structure. */ + gs_display_get_callback_t *cb = (gs_display_get_callback_t *)data; + cb->callback = &display_callback; + cb->caller_handle = callout_handle; + return 0; + } + return -1; + } + + +As you can see, this callout handler only responds to callouts for the display device, and then only for one particular function (``id``). It returns the same ``display_callback`` structure as the deprecated, legacy mechanism passed in using ``gsapi_set_display_callback``, with the added benefit that the ``caller_handle`` value can be passed in too. In this example we pass in the same value as was used for ``callout_handle``, but implementations are free to use any value they want. + +Returning to our example, we now set up a set of arguments to setup Ghostscript: + + +.. code-block:: c + + int argc = 0; + /* Allow for up to 32 args of up to 64 chars each. */ + char argv[32][64]; + sprintf(argc[argc++], "gs"); + sprintf(argv[argc++], "-sDEVICE=display"); + + +The zeroth arg is a dummy argument to match the standard C mechanism for passing arguments to a program. Traditionally this is the name of the program being invoked. Next, we tell Ghostscript to use the display device. + +.. code-block:: c + + sprintf(argv[argc++], "-sDEVICE=display"); + +Next we tell the display device what output format to use. The format is flexible enough to support common Windows, OS/2, Linux and Mac raster formats. + +The format values are described in ``gdevdsp.h``. To select the display device with a Windows 24-bit RGB raster: + +.. code-block:: c + + sprintf(argv[argc++], "-dDisplayFormat=%d", + DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | + DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST); + + +If (and only if) you used the legacy mechanism described above, you will need another argument to pass in the ``caller_handle`` value to be parroted back to the functions listed within ``display_callback``: + + +.. code-block:: c + + sprintf(arg2, "-dDisplayHandle=%d", callout_handle); + + +Any other arguments that you want can be added to the end of the command line, typically including a file to run. Then we pass that all to Ghostscript: + + +.. code-block:: c + + code = gsapi_init_with_args(minst, argc, argv); + + +At this point you should start to see your display callback functions being called. Exactly which callback functions are provided, and how they respond will determine exactly how the display device operates. The primary choice will be whether the device runs in "full page" or "rectangle request" mode. Details of these are given below. + +Once we have finished processing the file, we can process other files using ``gsapi_run_file``, or feed in data using ``gsapi_run_string``. Once you have finished, you can shut the interpreter down and exit, using: + +.. code-block:: c + + code = gsapi_exit(minst); + gsapi_delete_instance(minst); + +A full list of the display callback functions can be found in ``gdevdsp.h``. There are several different versions of the callback, corresponding to different "generations" of the device. In general you should use the latest one. The size field of the structure should be initialised to the size of the structure in bytes. + + +display_open() +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + int (*display_open)(void *handle, void *device); + +This function will be called when the display device is opened. The device may be opened and closed many times, sometimes without any output being produced. + + +display_preclose() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_preclose)(void *handle, void *device); + + +This function will be called when the display device is about to be closed. The device will not actually be closed until this function returns. + + + +display_close() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_close)(void *handle, void *device); + + +This function will be called once the display device has been closed. There will be no more events from the device unless/until it is reopened. + + + +display_presize() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_presize)(void *handle, void *device, + int width, int height, int raster, unsigned int format); + + +This function will be called when the display device is about to be resized. The device will only be resized if this function returns 0. + + + + +display_size() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_size)(void *handle, void *device, int width, int height, + int raster, unsigned int format, unsigned char *pimage); + + +This function will be called when the display device is has been resized. The pointer to the raster image is pimage. + + + +display_sync() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_sync)(void *handle, void *device); + + +This function may be called periodically during display to flush the page to the display. + + + +display_page() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_page)(void *handle, void *device, int copies, int flush); + + +This function is called on a "showpage" operation (i.e. at the end of every page). Operation will continue as soon as this function returns. + + + + +display_update() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_update)(void *handle, void *device, + int x, int y, int w, int h); + + +This function may get called repeatedly during rendering to indicate that an area of the output has been updated. Certain types of rendering will not see this function called back at all (in particular files using transparency). + + + + +display_memalloc() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_memalloc)(void *handle, void *device, + size_t long size); + + +Note: In older versions of this API, size is an unsigned long rather than a ``size_t``. + + +If this function pointer is sent as ``NULL``, then the display device will handle all the memory allocations internally, and will always work in full page rendering mode. + +Otherwise, this function will be called to allocate the storage for the page to be rendered into. If a non-NULL value is returned, then the device will proceed to render the full page into it. If ``NULL`` is returned, then the device will check a) whether we are using a V2 or greater display callback structure and b) whether that structure specifies a rectangle_request function pointer. + +If both of those conditions are true, then the device will continue in rectangle request mode. Otherwise it will fail with an out of memory error. + + + + +display_memfree() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_memfree)(void *handle, void *device, void *ptr); + + +This function should be ``NULL`` if and only if ``display_memalloc`` is ``NULL``. Any memory allocated using ``display_memalloc`` will be freed via this function. + + +display_separation() +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_separation)(void *handle, void *device, + int component, const char *component_name, + unsigned short c, unsigned short m, + unsigned short y, unsigned short k); + + +When using ``DISPLAY_COLORS_SEPARATION``, this function will be called once for every separation component - first "Cyan", "Magenta", "Yellow" and "Black", then any spot colors used. The supplied c, m, y and k values give the equivalent color for each spot. Each colorant value ranges from 0 (for none) to 65535 (full). + +In separation color mode you are expected to count the number of calls you get to this function after each ``display_size`` to know how many colors you are dealing with. + + + +display_adjust_band_height() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_adjust_band_height)(void *handle, void *device, + int bandheight); + + +When running in "rectangle request mode" the device first renders the page to a display list internally. It can then be played back repeatedly so that different regions (rectangles) of the page can be extracted in sequence. A common use of this is to support "banded" operation, where the page is divided into multiple non-overlapping bands of a fixed height. + +The display device itself will pick an appropriate band height for it to use. If this function pointer is left as ``NULL`` then this value will be used unchanged. Otherwise, the proposed value will be offered to this function. This function can override the choice of bandheight, by returning the value that it would like to be used in preference. + +In general, this figure should (as much as possible) only be adjusted downwards. For example, a device targeting an inkjet printer with 200 nozzles in the print head might like to extract bands that are a multiple of 200 lines high. So the function might ``return max(200, 200*(bandheight/200))``. If the function returns 0, then the existing value will be used unchanged. + + +Any size rectangle can be chosen with any size bandheight, so ultimately the value chosen here will not matter much. It may make some small difference in speed in some cases. + + + +display_rectangle_request() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + int (*display_rectangle_request)(void *handle, void *device, + void **memory, int *ox, int *oy, + int *raster, int *plane_raster, + int *x, int *y, int *w, int *h); + + +If the display device chooses to use rectangle request mode, this function will be called repeatedly to request a rectangle to render. Ghostscript will render the rectangle, and call this function again. The implementer is expected to handle the rectangle that has just been rendered, and to return the details of another rectangle to render. This will continue until a rectangle with zero height or width is returned, whereupon Ghostscript will continue operation. + +On entry, ``*raster`` and ``*plane_raster`` are set to the values expected by the format in use. All the other pointers point to uninitialised values. + +On exit, the values should be updated appropriately. The implementor is expected to store the values returned so that the rendered output given can be correctly interpreted when control returns to this function. + +``memory`` should be updated to point to a block of memory to use for the rendered output. Pixel (``*ox``, ``*oy``) is the first pixel represented in that block. + +``*raster`` is the number of bytes difference between the address of component 0 of Pixel(``*ox``, ``*oy``) and the address of component 0 of Pixel(``*ox``, 1+``*oy``). + +``*plane_raster`` is the number of bytes difference between the address of component 0 of Pixel(``*ox``, ``*oy``) and the address of component 1 of Pixel(``*ox``, ``*oy``), if in planar mode, 0 otherwise. ``*x``, ``*y``, ``*w`` and ``*h`` give the rectangle requested within that memory block. + +Any set of rectangles can be rendered with this method, so this can be used to drive Ghostscript in various ways. Firstly, it is simple to request a set of non-overlapping "bands" that cover the page, to drive a printer. Alternatively, rectangles can be chosen to fill a given block of memory to implement a window panning around a larger page. Either the whole image could be redrawn each time, or smaller rectangles around the edge of the panned area could be requested. The choice is down to the caller. + +Some examples of driving this code in full page mode are in ```dwmain.c``(Windows), ``dpmain.c`` (OS/2) and ``dxmain.c`` (X11/Linux), and ``dmmain.c`` (MacOS Classic or Carbon). + +Alternatively an example that drives this code in both full page and rectangle request mode can be found in ``api_test.c``. + +On some platforms, the calling convention for the display device callbacks in ``gdevdsp.h`` is not the same as the exported :ref:`gsapi_*() <gsapi_asterisk>` functions in ``iapi.h``. + + + +.. include:: footer.rst + + + + + + + + + diff --git a/doc/src/C-style.rst b/doc/src/C-style.rst new file mode 100644 index 00000000..0837e89c --- /dev/null +++ b/doc/src/C-style.rst @@ -0,0 +1,1060 @@ +.. title:: Ghostscript C Coding Guidelines + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _C-style.htm: + + +Ghostscript C Coding Guidelines +=================================== + + +This document describes Ghostscript's C coding conventions. It is primarily prescriptive, documenting what developers should do when writing new code; the companion :ref:`developer documentation<Develop.htm>` is primarily descriptive, documenting the way things are. + +We encourage following the general language usage and stylistic rules for any code that will be integrated with Ghostscript, even if the code doesn't use Ghostscript's run-time facilities or have anything to do with PostScript, PDF, or page description languages. Ghostscript itself follows some additional conventions; these are documented separately under :ref:`Ghostscript conventions<Conventions>` below. + + + +C language do's and don'ts +------------------------------ + +There are several different versions of the C language, and even of the ANSI C standard. Ghostscript versions through 7.0 were designed to compile on pre-ANSI compilers as well as on many compilers that implemented the ANSI standard with varying faithfulness. Ghostscript versions since 7.0 do not cater for pre-ANSI compilers: they must conform to the ANSI 1989 standard (ANS X3.159-1989), with certain restrictions and a few conventional additions. + +Preprocessor +~~~~~~~~~~~~~~~~ + +Conditionals +""""""""""""""" + +Restrictions: + +- Don't assume that ``#if`` will treat undefined names as 0. While the ANSI standard requires this, it may produce a warning. + +- In ``.c`` files, don't use preprocessor conditionals that test for individual platforms or compilers. Use them only in header files named ``xxx_.h``. + + +Macros +""""""""""" + +Restrictions: + +- Don't redefine a macro, even with the same definition, without using ``#undef``. + +- ``CAPITALIZE`` macro names unless there is a good reason *not* to. + +- Even though the legacy code contains some macros which contain control flow statments, avoid the use of this in new code and do not create macros which contain hidden control flow, especially 'return'. The use of control flow in macros complicates debug significantly requiring tedious expansion of macros to build a module to be debugged or resorting to disassembly windows to set breakpoints or to trace flow. + +- Don't use a macro call within a macro argument if the call expands to a token sequence that includes any commas not within parentheses: this produces different results depending on whether the compiler expands the inner call before or after the argument is substituted into the macro body. (The ANSI standard says that calls must be expanded after substitution, but some compilers do it the other way.) + +- Don't use macro names, even inadvertently, in string constants. Some compilers erroneously try to expand them. + +- Don't use macros to define shorthands for casted pointers. For instance, avoid: + + + .. code-block:: c + + #define fdev ((gx_device_fubar *)dev) + + and instead use: + + + .. code-block:: c + + gx_device_fubar * const fdev = (gx_device_fubar *)dev; + + + The use of ``const`` alerts the reader that this is effectively a synonym. + +- If a macro generates anything larger than a single expression (that is, one or more statements), surround it with ``BEGIN`` and ``END``. These work around the fact that simple statements and compound statements in C can't be substituted for each other syntactically. + + +- If a macro introduces local variables, only use names that end with an underscore (``_``), such as ``code_``. This avoids clashes both with ordinary variable names (which should never end with an underscore) and with system-defined names (which may begin with an underscore). + + +Other +~~~~~~~~~~~~~~~~ + +Restrictions: + +Only use ``#pragma`` in files that are explicitly identified as being platform-dependent. Many compilers complain if this is used at all, and some complain if they don't recognize the specific ``pragma`` being requested (both incorrect according to the ANSI standard). + + +Lexical elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Do not use: + +- ANSI trigraphs (``??x``). + +- Nested comments (``/* /* */ */``) (not ANSI compliant, but often accepted). + +- Multi-character character constants ('abc'). + +- Wide-character character or string constants (``L'x'``, ``L"x"``). + +Restrictions: + +- Procedure and static variable names must be 31 characters or less. + +- Externally visible procedure and variable names must be unique in the first 23 characters. + + +Scoping (extern, static, ...) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Do not use: + +- ``register`` + +Restrictions: + +- Do not allow a global variable (constant) to have more than one non-``extern`` definition, even though some ANSI C compilers allow this. Every global constant should have exactly one definition, in a ``.c`` file, and preferably just one ``extern`` declaration, in a header file. + + +- ``static`` or variables must be ``const`` and initialized: non-``const`` statically allocated variables are incompatible with reentrancy, and we're in the process of eliminating all of them. + +- Do not use ``extern`` in ``.c`` files, only in ``.h`` files, unless you have a very good reason for it (e.g., as in ``iconf.c``). There are too many such externs in the code now: we are eliminating them over time. + +- Do not declare the same name as both ``static`` and non-``static`` within the same compilation. (Some compilers complain, some do not.) This is especially a problem for procedures: it is easy to declare a procedure as ``static`` near the beginning of a file and accidentally not declare it ``static`` where it is defined later in the file. + +- Even though the ANSI standard allows initialized external declarations (``extern int x = 0``), don't use them. + + +Scalars +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Restrictions: + +- Avoid using ``char``, except for ``char *`` for a pointer to a string. Don't assume that ``char`` is signed; also don't assume it is unsigned. + +- Never cast a ``float`` to a ``double`` explicitly. ANSI compilers in their default mode do all floating point computations in double precision, and handle such casts automatically. + +- Don't use ``long long``: even though it is in the ANSI standard, not all compilers support it. Use the ``(u)int64_t`` types from ``stdint_.h`` instead. + +- Don't assume anything about whether ``sizeof(long)`` is less than, equal to, or greater than ``sizeof(ptr)``. (However, you can make such comparisons in preprocessor conditionals using ``ARCH_SIZEOF_LONG`` and ``ARCH_SIZEOF_PTR``). + + +Arrays +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Don't declare arrays of size 0. (The newer ANSI standard allows this, but the older one doesn't). + +- Don't declare an array of size 1 at the end of a structure to indicate that a variable-size array follows. + +- Don't declare initialized ``auto`` arrays. + + +Typedefs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Don't use ``typedef`` for function types, such as: + +.. code-block:: c + + typedef int proc_xyz_t(double, int *); + + +Many compilers don't handle this correctly -- they will give errors, or do the wrong thing, when declaring variables of type ``proc_xyz_t`` and/or ``proc_xyz_t *``. Instead, do this: + +.. code-block:: c + + #define PROC_XYZ(proc) int proc(double, int *) + PROC_XYZ(some_proc); /* declare a procedure of this type */ + typedef PROC_XYZ((*proc_xyz_ptr_t)); /* define a type for procedure ptrs */ + + proc_xyz_ptr_t pp; /* pointer to procedure */ + + +Don't redefine ``typedef``'ed names, even with the same definition. Some compilers complain about this, and the standard doesn't allow it. + + +Structures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Don't use anonymous structures if you can possibly avoid it, except occasionally as components of other structures. Ideally, use the ``struct`` keyword only for declaring named structure types, like this: + +.. code-block:: c + + typedef struct xxx_s { + ... members ... + } xxx_t; + +- Use ``struct`` only when declaring structure types, never for referring to them (e.g., never declare a variable as type ``struct xxx_s *``). + +- Don't assume that the compiler will (or won't) insert padding in structures to align members for best performance. To preserve alignment, only declare structure members that are narrower than an ``int`` if there will be a lot of instances of that structure in memory. For such structures, insert ``byte`` and/or ``short`` padding members as necessary to re-establish ``int`` alignment. + +- Don't declare initialized ``auto`` structures. + + +Unions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Use unions only as components of structures, not as ``typedefs`` in their own right. + +- Don't attempt to initialize unions: not all compilers support this, even though it is in the 1989 ANSI standard. + + +Expressions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Don't assign a larger integer data type to a smaller one without a cast (``int_x = long_y``). + +- It's OK to use the address of a structure or array element (``&p->e, &a[i]``) locally, or pass it to a procedure that won't store it, but don't store such an address in allocated storage unless you're very sure of what you're doing. + +- Don't use conditional expressions with structure or union values. (Pointers to structures or unions are OK). + +- For calling a variable or parameter procedure, use ``ptr->func(...)``. Some old code uses explicit indirection, ``(*ptr->func)(...)``: don't use this in new code. + +- Don't write expressions that depend on order of evaluation, unless the order is created explicitly by use of ``||``, ``&&``, ``?:``, ``,``, or function nesting (the arguments of a function must be evaluated before the function is called). In particular, don't assume that the arguments of a function will be evaluated left-to-right, or that the left side of an assignment will be evaluated before the right. + +- Don't mix integer and enumerated types ad lib: treat enumerated types as distinct from integer types, and use casts to convert between the two. (- Some compilers generate warnings if you do not do this). + + +Statements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- If you use an expression as a statement, other than an assignment or a function call with void return value, enclose it explicitly in ``DISCARD()``. + +- The type of the operand of a ``switch`` must match the type of the case labels, whether the labels are ``ints`` or the members of an ``enum`` type. (Use a cast if necessary). + +- It is OK for one case of a switch to "fall through" into another (i.e., for the statement just before a case label not to be a control transfer), but a comment ``/* falls through */`` is required. + +- If you are returning an error code specified explicitly (e.g., ``return gs_error_rangecheck``), use ``return_error()`` rather than plain ``return``. However, if the program is simply propagating an error code generated elsewhere, as opposed to generating the error, use return (e.g., ``if (code < 0) return code``). + + +Procedures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Provide a prototype for every procedure, and make sure the prototype is available at every call site. If the procedure is local to a file (static), the prototype should precede the procedure, in the same file; if the procedure is global, the prototype should be in a header file. + +- If a procedure parameter is itself a procedure, do list its parameter types rather than just using ``()``. For example: + + .. code-block:: c + + int foo(int (*callback)(int, int)); + + rather than just: + + .. code-block:: c + + int foo(int (*callback)()); + +- Don't use the ``P*`` macros in new code. (See the Procedures section of `Language extensions`_ below for more information.) + +- Always provide an explicit return type for procedures, in both the prototype and the definition: don't rely on the implicit declaration as ``int``. + +- Don't use ``float`` as the return type of a procedure, unless there's a special reason. Floating point hardware typically does everything in double precision internally and has to do extra work to convert between double and single precision. + +- Don't declare parameters as being of type ``float``, ``short``, or ``char``. If you do this and forget to include the prototype at a call site, ANSI compilers will generate incompatible calling sequences. Use ``double`` instead of ``float``, and use ``int`` or ``uint`` instead of ``short`` or ``char``. + + +Standard library +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restrictions: + +- Only use library features that are documented in the established ANSI standard (e.g., Harbison & Steele's book). Do not use procedures that are "standards" promulgated by Microsoft (e.g., ``stricmp``), or originate in BSD Unix (e.g., ``strcasecmp``), or were added in later versions of the standard such as C 9X. + +- Do not use any features from ``stdio.h`` that assume the existence of ``stdin``, ``stdout``, or ``stderr``. See ``gsio.h`` for the full list. Instead, use ``gs_stdin`` *et al*. + + + +Language extensions +----------------------- + + +Scoping +~~~~~~~~~~ + +``static`` + Ghostscript assumes the compiler supports the ``static`` keyword for declaring variables and procedures as local to a particular source file. + +``inline`` + ``inline`` is available even if the compiler does not support it. Be aware, however, that it may have no effect. In particular, do not use ``inline`` in header files. Instead, use the ``extern_inline`` facility described just below. + +``extern_inline`` + Compilers that do support ``inline`` vary in how they decide whether to (also) compile a closed-code copy of the procedure. Because of this, putting an ``inline`` procedure in a header file may produce multiple closed copies, causing duplicate name errors at link time. ``extern_inline`` provides a safe way to put ``inline`` procedures in header files, regardless of compiler. Unfortunately, the only way we've found to make this fully portable involves a fair amount of boilerplate. For details, please see ``stdpre.h``. + +Scalar types +~~~~~~~~~~~~~~~~~~ + +``bool``, ``true``, ``false`` + ``bool`` is intended as a ``Boolean`` type, with canonical values ``true`` and ``false``. In a more reasonable language, such as Java, ``bool`` is an enumerated type requiring an explicit cast to or from ``int``; however, because C's conditionals are defined as producing ``int`` values, we can't even define ``bool`` as a C ``enum`` without provoking compiler warnings. + + Even though ``bool`` is a synonym for ``int``, treat them as conceptually different types: + + - Initialize or set ``bool`` variables to ``true`` or ``false``, not ``0`` or ``1``. + + - Use the ``Boolean`` operators ``!``, ``&&``, and ``||`` only with ``Booleans``. Don't use the idiom ``!!x`` to create a ``Boolean`` that is true ``iff x != 0``: use ``x != 0``. + + - Use an explicit (``int``) cast to convert a ``Boolean`` to an ``integer``. + +``byte``, ``ushort``, ``uint``, ``ulong`` + These types are simply shorthands for unsigned ``char``, ``short``, ``int``, ``long``. + + In addition, the use of ``byte *`` indicates a Ghostscript-style string, with explicit length given separately, as opposed to a null terminated C-style string, which is ``char *``. + +``bits8``, ``bits16``, ``bits32`` + These are unsigned ``integer`` types of the given width. Use them wherever the actual width matters: do *not*, for example, use short assuming that it is 16 bits wide. New code can use the C99 fixed-width types from ``stdint_.h``. + + + +.. _Conventions: + + +Stylistic conventions +-------------------------------- + +Ghostscript's coding rules cover not only the use of the language, but also many stylistic issues like the choice of names and the use of whitespace. The stylistic rules are meant to produce code that is easy to read. It's important to observe them as much as possible in order to maintain a consistent style, but if you find these rules getting in your way or producing ugly-looking results once in a while, it's OK to break it. + +Formatting +~~~~~~~~~~~~~ + +Indentation +""""""""""""""" + +We've formatted all of our code using the GNU ``indent`` program. + +.. code-block:: bash + + indent -bad -nbap -nsob -br -ce -cli4 -npcs -ncs \ + -i4 -di0 -psl -lp -lps -nut somefile.c + +does a 98% accurate job of producing our preferred style. Unfortunately, there are bugs in all versions of GNU ``indent``, requiring both pre- and post-processing of the code. + +Put indentation points every 4 spaces. Never use tab stops! + +Don't indent the initial ``#`` of preprocessor commands. However, for nested preprocessor commands, do use indentation between the ``#`` and the command itself. Use 2 spaces per level of nesting, e.g.: + +.. code-block:: c + + #ifndef xyz + # define xyz 0 + #endif + +For assignments (including chain assignments), put the entire statement on one line if it will fit; if not, break it after a ``=`` and indent all the following lines. I.e., format like this: + +.. code-block:: c + + var1 = value; + var1 = var2 = value; + var1 = + value; + var1 = + var2 = value; + var1 = var2 = + value; + + +But not like this: + +.. code-block:: c + + var1 = + var2 = value; + + + +Indent in-line blocks thus: + +.. code-block:: c + + { + ... declarations ... + {{ blank line if any declarations above }} + ... statements ... + } + +Similarly, indent procedures thus: + +.. code-block:: c + + return_type + proc_name(... arguments ...) + { + ... declarations ... + {{ blank line if any declarations above }} + ... statements ... + } + + +If a control construct (if, do, while, or for) has a one-line body, use this: + +.. code-block:: c + + ... control construct ... + ... subordinate simple statement ... + +This is considered particularly important so that a breakpoint can be set inside the conditional easily. + +If it has a multi-line body, use this: + +.. code-block:: c + + ... control construct ... { + ... subordinate code ... + } + + +If the subordinate code has declarations, see blocks above. + +For if-else statements, do this: + + +.. code-block:: c + + if ( ... ) { + ... subordinate code ... + } else if ( ... ) { + ... subordinate code ... + } else { + ... subordinate code ... + } + + + +When there are more than two alternatives, as in the example above, use the above ("parallel") syntax rather than the following ("nested") syntax: + + +.. code-block:: c + + if ( ... ) { + ... subordinate code ... + } else { + if ( ... ) { + ... subordinate code ... + } else { + ... subordinate code ... + } + } + +Similarly, for do-while statements, do this: + +.. code-block:: c + + do { + ... body ... + } while ( ... condition ... ); + + + + +Spaces +""""""""""""""" + +Do put a space: + +- After every comma and semicolon, unless it ends a line. + +- Around every binary operator other than "``->``" and "``.``", although you can omit the spaces around the innermost operator in a nested expression if you like. + +- On both sides of the parentheses of an if, for, or while. + + +Don't put a space: + +- At the end of a line. + +- Before a comma or semicolon. + +- After unary prefix operators. + +- Before the parenthesis of a macro or procedure call. + + + +Parentheses +""""""""""""""" + +Parentheses are important in only a few places: + +- Around the inner subexpressions in expressions that mix ``&&`` and ``||``, even if they are not required by precedence, for example: + .. code-block:: c + + (xx && yy) || zz + +- Similarly around inner subexpressions in expressions that mix ``&``, ``|``, or shifts, especially if mixing these with other operators, for instance: + .. code-block:: c + + (x << 3) | (y >> 5) + +- In macro definitions around every use of an argument that logically could be an expression, for example: + .. code-block:: c + + ((x) * (x) + (y) * (y)) + + +Anywhere else, given the choice, use fewer parentheses. + + + + +For stylistic consistency with the existing Ghostscript code, put parentheses around conditional expressions even if they aren't syntactically required, unless you really dislike doing this. Note that the parentheses should go around the entire expression, not the condition. For instance, instead of: + +.. code-block:: c + + hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, + (pgls->g.pen_down) ? gs_lineto : gs_moveto); + +use: + +.. code-block:: c + + hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, + (pgls->g.pen_down ? gs_lineto : gs_moveto)); + + + + + + +Preprocessor +~~~~~~~~~~~~~~ + +Conditionals +"""""""""""""" + +Using preprocessor conditionals can easily lead to unreadable code, since the eye really wants to read linearly rather than having to parse the conditionals just to figure out what code is relevant. It's OK to use conditionals that have small scope and that don't change the structure or logic of the program (typically, they select between different sets of values depending on some configuration parameter), but where possible, break up source modules rather than use conditionals that affect the structure or logic. + +Macros +""""""""""""" + +Ghostscript code uses macros heavily to effectively extend the rather weak abstraction capabilities of the C language, specifically in the area of memory management and garbage collection: in order to read Ghostscript code effectively, you simply have to learn some of these macros as though they were part of the language. The current code also uses macros heavily for other purposes, but we are trying to phase these out as rapidly as possible, because they make the code harder to read and debug, and to use the rules that follow consistently in new code. + +Define macros in the smallest scope you can manage (procedure, file, or ``.h`` file), and ``#undef`` them at the end of that scope: that way, someone reading the code can see the definitions easily when reading the uses. If that isn't appropriate, define them in as large a scope as possible, so that they effectively become part of the language. This places an additional burden on the reader, but it can be amortized over reading larger amounts of code. + +Try hard to use procedures instead of macros. Use "``inline``" if you really think the extra speed is needed, but only within a ``.c`` file: don't put inline procedures in ``.h`` files, because most compilers don't honor "``inline``" and you'll wind up with a copy of the procedure in every ``.c`` file that includes the ``.h`` file. + +If you define a macro that looks like a procedure, make sure it will work wherever a procedure will work. In particular, put parentheses around every use of an argument within the macro body, so that the macro will parse correctly if some of the arguments are expressions, and put parentheses around the entire macro body. (This is still subject to the problem that an argument may be evaluated more than once, but there is no way around this in C, since C doesn't provide for local variables within expressions.) + +If you define macros for special loop control structures, make their uses look somewhat like ordinary loops, for instance: + + +.. code-block:: c + + BEGIN_RECT(xx, yy) { + ... body indented one position ... + } END_RECT(xx, yy); + + + +If at all possible, don't use free variables in macros -- that is, variables that aren't apparent as arguments of the macro. If you must use free variables, list them all in a comment at the point where the macro is defined. + +If you define new macros or groups of macros, especially if they aren't simply inline procedures or named constant values, put some extra effort into documenting them, to compensate for the fact that macros are intrinsically harder to understand than procedures. + + +Comments +~~~~~~~~~~~~~~ + +The most important descriptive comments are ones in header files that describe structures, including invariants; but every procedure or structure declaration, or group of other declarations, should have a comment. Don't spend a lot of time commenting executable code unless something unusual or subtle is going on. + +Naming +~~~~~~~~~~~~~~ + +Use fully spelled-out English words in names, rather than contractions. This is most important for procedure and macro names, global variables and constants, values of ``#define`` and ``enum``, ``struct`` and other ``typedef`` names, and structure member names, and for argument and variable names which have uninformative types like ``int``. It's not very important for arguments or local variables of distinctive types, or for local index or count variables. + +Avoid names that run English words together: "``hpgl_compute_arc_center``" is better than "``hpgl_compute_arccenter``". However, for terms drawn from some predefined source, like the names of PostScript operators, use a term in its well-known form (for instance, ``gs_setlinewidth`` rather than ``gs_set_line_width``). + +Procedures, variables, and structures visible outside a single ``.c`` file should generally have prefixes that indicate what subsystem they belong to (in the case of Ghostscript, ``gs_`` or ``gx_``). This rule isn't followed very consistently. + + +Types +~~~~~~~~~~~~~~ + +Many older structure names don't have ``_t`` on the end, but this suffix should be used in all new code. (The ``_s`` structure name is needed only to satisfy some debuggers. No code other than the structure declaration should refer to it.) + +Declare structure types that contain pointers to other instances of themselves like this: + +.. code-block:: c + + typedef struct xxx_s xxx_t; + struct xxx_s { + ... members ... + xxx_t *ptr_member_name; + ... members ... + }; + + +If, to maintain data abstraction and avoid including otherwise unnecessary header files, you find that you want the type ``xxx_t`` to be available in a header file that doesn't include the definition of the structure ``xxx_s``, use this approach: + + +.. code-block:: c + + #ifndef xxx_DEFINED + # define xxx_DEFINED + typedef struct xxx_s xxx_t; + #endif + struct xxx_s { + ... members ... + }; + + +You can then copy the first 4 lines in other header files. (Don't ever include them in an executable code file.) + +Don't bother using ``const`` for anything other than with pointers as described below. However, in those places where it is necessary to cast a pointer of type ``const T *`` to type ``T *``, always include a comment that explains why you are "breaking const". + +Pointers +""""""""""""""""""""" + +Use ``const`` for pointer referents (that is, ``const T *``) wherever possible and appropriate. + +If you find yourself wanting to use ``void *``, try to find an alternative using unions or (in the case of super- and subclasses) casts, unless you're writing something like a memory manager that really treats memory as opaque. + + + + +Procedures +~~~~~~~~~~~~~~~~~~~~~~~ + +In general, don't create procedures that are private and only called from one place. However, if a compound statement (especially an arm of a conditional) is too long for the eye easily to match its enclosing braces "``{...}``" -- that is, longer than 10 or 15 lines -- and it doesn't use or set a lot of state held in outer local variables, it may be more readable if you put it in a procedure. + +Miscellany +"""""""""""""""" + +Local variables +^^^^^^^^^^^^^^^^^^^^^ + +Don't assign new values to procedure parameters. It makes debugging very confusing when the parameter values printed for a procedure are not the ones actually supplied by the caller. Instead use a separate local variable initialized to the value of the parameter. + +If a local variable is only assigned a value once, assign it that value at its declaration, if possible. For example, + +.. code-block:: c + + int x = some expression ; + +rather than: + +.. code-block:: c + + int x; + ... + x = some expression ; + +Use a local pointer variable like this to "narrow" pointer types: + +.. code-block:: c + + int + someproc(... gx_device *dev ...) + { + gx_device_printer *const pdev = (gx_device_printer *)dev; + ... + } + +Don't "shadow" a local variable or procedure parameter with an inner local variable of the same name. I.e., don't do this: + +.. code-block:: c + + int + someproc(... int x ...) + { + ... + int x; + ... + } + + + +Compiler warnings +~~~~~~~~~~~~~~~~~~~~~~~ + +We want Ghostscript to compile with no warnings. This is a constant battle as compilers change and new code is added. Work hard to eliminate warnings by improving the code structure instead of patching over them. If the compiler can't figure out that a variable is always initialized, a future reader will probably have trouble as well. + + + + +File structuring +-------------------- + +All files +~~~~~~~~~~~~~~~~~~ + +Keep file names within the "8.3" format for portability: + +- Use only letters, digits, dash, and underscore in file names. + +- Don't assume upper and lower case letters are distinct. + +- Put no more than 8 characters before the ".", if any. + +- If there is a ".", put between 1 and 3 characters after the ".". + +For files other than documentation files, use only lower case letters in the names; for HTML documentation files, capitalize the first letter. + +Every code file should start with comments containing: + +#. A copyright notice. + +#. The name of the file in the form of an RCS Id: + +.. code-block:: + + /* $Id: filename.ext $*/ + +(using the comment convention appropriate to the language of the file), and + +3. A summary, no more than one line, of what the file contains. + +If you create a file by copying the beginning of another file, be sure to update the copyright year and change the file name. + + + +.. _CStyle_Makefiles: + +Makefiles +~~~~~~~~~~~~~~~~~~ + + +Use the extension ``.mak`` for ``makefiles``. + +For each: + +.. code-block:: c + + #include "xxx.h" + +make sure there is a dependency on ``$(xxx_h)`` in the makefile. If ``xxx`` ends with a "``_``", this rule still holds, so that if you code: + +.. code-block:: c + + #include "math_.h" + +the ``makefile`` must contain a dependency on "``$(math__h)``" (note the two underscores "``__``"). + +List the dependencies bottom-to-top, like the ``#include`` statements themselves; within each level, list them alphabetically. Do this also with ``#include`` statements themselves whenever possible (but sometimes there are inter-header dependencies that require bending this rule). + +For compatibility with the build utilities on OpenVMS, always put a space before the colon that separates the target(s) of a rule from the dependents. + + +General C code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +List ``#include`` statements from "bottom" to "top", that is, in the following order: + +#. System includes ("``xxx_.h``"). + +#. ``gs*.h`` + +#. ``gx*.h`` (yes, ``gs`` and ``gx`` are in the wrong order). + +#. ``s*.h`` + +#. ``i*.h`` (or other interpreter headers that don't start with "``i``"). + + +Headers (.h files) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In header files, always use the following at the beginning of a header file to prevent double inclusion: + +.. code-block:: c + + {{ Copyright notice etc. }} + + #ifndef <filename>_INCLUDED + #define <filename>_INCLUDED + + {{ The contents of the file }} + + #endif /* <filename>_INCLUDED */ + + +The header file is the first place that a reader goes for information about procedures, structures, constants, etc., so ensure that every procedure and structure has a comment that says what it does. Divide procedures into meaningful groups set off by some distinguished form of comment. + + + +Source (.c files) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After the initial comments, arrange C files in the following order: + +#. ``#include`` statements. + +#. Exported data declarations. + +#. Explicit externs (if necessary). + +#. Forward declarations of procedures. + +#. Private data declarations. + +#. Exported procedures. + +#. Private procedures. + + +Be flexible about the order of the declarations if necessary to improve readability. Many older files don't follow this order, often without good reason. + + +Ghostscript conventions +----------------------------- + +Specific names +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Ghostscript code uses certain names consistently for certain kinds of values. Some of the commonest and least obvious are these two: + + + +code +""""""" + +A value to be returned from a procedure. + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - < 0 + - An error code defined in ``gserrors.h`` (or ``ierrors.h``) + * - 0 + - Normal return + * - > 0 + - A non-standard but successful return (which must be documented, preferably with the procedure's prototype) + + + +status +""""""" + +A value returned from a *stream* procedure. + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - < 0 + - An exceptional condition as defined in ``scommon.h`` + * - 0 + - Normal return (or, from the "process" procedure, means that more input is needed) + * - 1 + - More output space is needed (from the "process" procedure) + + + + +Structure type descriptors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Ghostscript memory manager requires run-time type information for every structure. (We don't document this in detail here: see the :ref:`Structure descriptors<Develop_Structure_Descriptors>` section of the developer documentation for details.) Putting the descriptor for a structure next to the structure definition will help keep the two consistent, so immediately after the definition of a structure ``xxx_s``, define its structure descriptor: + +.. code-block:: c + + struct xxx_s { + ... members ... + }; + #define private_st_xxx() /* in <filename>.c */\ + gs_private_st_<whatever>(st_xxx, xxx_t,\ + "xxx_t", xxx_enum_ptrs, xxx_reloc_ptrs,\ + ... additional parameters as needed ...) + +The file that implements operations on this structure (``<filename>.c``) should then include, near the beginning, the line: + + +.. code-block:: c + + private_st_xxx(); + + +In much existing code, structure descriptors are declared as public, which allows clients to allocate instances of the structure directly. We now consider this bad design. Instead, structure descriptors should always be static; the implementation file should provide one or more procedures for allocating instances, e.g., + +.. code-block:: c + + xxx_t *gs_xxx_alloc(P1(gs_memory_t *mem)); + + +If it is necessary to make a structure descriptor public, it should be declared in its clients as: + +.. code-block:: c + + extern_st(st_xxx); + + +.. _CStyle_Objects: + + +"Objects" +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript makes heavy use of object-oriented constructs, including analogues of classes, instances, subclassing, and class-associated procedures. However, these constructs are implemented in C rather than C++, for two reasons: + +The first Ghostscript code was written in 1986, long before C++ was codified or was well supported by tools. Even today, C++ tools rarely support C++ as well as C tools support C. + +C++ imposes its own implementations for virtual procedures, inheritance, run-time type information, and (to some extent) memory management. Ghostscript requires use of its own memory manager, and also sometimes requires the ability to change the virtual procedures of an object dynamically. + +Classes +""""""""" + +The source code representation of a class is simply a ``typedef`` for a C ``struct``. See Structures_, above, for details. + +Procedures +""""""""""" + +Ghostscript has no special construct for non-virtual procedures associated with a class. In some cases, the ``typedef`` for the class is in a header file but the struct declaration is in the implementation code file: this provides an extra level of opaqueness, since clients then can't see the representation and must make all accesses through procedures. You should use this approach in new code, if it doesn't increase the size of the code too much or require procedure calls for very heavily used accesses. + +Ghostscript uses three different approaches for storing and accessing virtual procedures, plus a fourth one that is recommended but not currently used. For exposition, we assume the class (type) is named ``xxx_t``, it has a virtual procedure ``void (*virtu)(P1(xxx_t *))``, and we have a variable declared as ``xxx_t *pxx``. + + + +#. The procedures are stored in a separate, constant structure of type ``xxx_procs``, of which ``virtu`` is a member. The structure definition of ``xxx_t`` includes a member defined as ``const xxx_procs *procs`` (always named ``procs``). The construct for calling the virtual procedure is ``pxx->procs->virtu(pxx)``. + +#. The procedures are defined in a structure of type ``xxx_procs`` as above. The structure definition of ``xxx_t`` includes a member defined as ``xxx_procs procs`` (always named ``procs``). The construct for calling the virtual procedure is ``pxx->procs.virtu(pxx)``. + +#. The procedures are not defined in a separate structure: each procedure is a separate member of ``xxx_t``. The construct for calling the virtual procedure is ``pxx->virtu(pxx)``. + +#. The procedures are defined in a structure of type ``xxx_procs`` as above. The structure definition of ``xxx_t`` includes a member defined as ``xxx_procs procs[1]`` (always named ``procs``). The construct for calling the virtual procedure is again ``pxx->procs->virtu(pxx)``. + +Note that in approach 1, the procedures are in a shared constant structure; in approaches 2 - 4, they are in a per-instance structure that can be changed dynamically, which is sometimes important. + +In the present Ghostscript code, approach 1 is most common, followed by 2 and 3; 4 is not used at all. For new code, you should use 1 or 4: that way, all virtual procedure calls have the same form, regardless of whether the procedures are shared and constant or per-instance and mutable. + +Subclassing +"""""""""""""""""" + +Ghostscript's class mechanism allows for subclasses that can add data members, or can add procedure members if approach 1 or 3 (above) is used. Since C doesn't support subclassing, we use a convention to accomplish it. In the example below, ``gx_device`` is the root class; it has a subclass ``gx_device_forward``, which in turn has a subclass ``gx_device_null``. First we define a macro for all the members of the root class, and the root class type. (As for structures in general, classes need a structure descriptor, as discussed in Structures_ above: we include these in the examples below.) + + +.. code-block:: c + + #define gx_device_common\ + type1 member1;\ + ... + typeN memberN + + typedef struct gx_device_s { + gx_device_common; + } gx_device; + + #define private_st_gx_device() /* in gsdevice.c */\ + gs_private_st_<whatever>(st_gx_device, gx_device,\ + "gx_device", device_enum_ptrs, device_reloc_ptrs,\ + ... additional parameters as needed ...) + + +We then define a similar macro and type for the subclass. + + +.. code-block:: c + + #define gx_device_forward_common\ + gx_device_common;\ + gx_device *target + + typedef struct gx_device_forward_s { + gx_device_forward_common; + } gx_device_forward; + + #define private_st_device_forward() /* in gsdevice.c */\ + gs_private_st_suffix_add1(st_device_forward, gx_device_forward,\ + "gx_device_forward", device_forward_enum_ptrs, device_forward_reloc_ptrs,\ + gx_device, target) + + +Finally, we define a leaf class, which doesn't need a macro because we don't currently subclass it. (We can create the macro later if needed, with no changes anywhere else.) In this particular case, the leaf class has no additional data members, but it could have some. + + +.. code-block:: c + + typedef struct gx_device_null_s { + gx_device_forward_common; + }; + + #define private_st_device_null() /* in gsdevice.c */\ + gs_private_st_suffix_add0_local(st_device_null, gx_device_null,\ + "gx_device_null", device_null_enum_ptrs, device_null_reloc_ptrs,\ + gx_device_forward) + + +.. note:: + + The above example is not the actual definition of the ``gx_device`` structure type: the actual type has some additional complications because it has a finalization procedure. See ``base/gxdevcli.h`` for the details. + +If you add members to a root class (such as ``gx_device`` in this example), or change existing members, do this in the ``gx_device_common`` macro, not the ``gx_device`` structure definition. Similarly, to change the ``gx_device_forward`` class, modify the ``gx_device_forward_common`` macro, not the structure definition. Only change the structure definition if the class is a leaf class (one with no ``_common`` macro and no possibility of subclassing), like ``gx_device_null``. + + +Error handling +~~~~~~~~~~~~~~~~~~~~~~ + +Every caller should check for error returns and, in general, propagate them to its callers. By convention, nearly every procedure returns an ``int`` to indicate the outcome of the call: + + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - < 0 + - Error return + * - 0 + - Normal return + * - > 0 + - Non-error return other than the normal case + + + +To make a procedure generate an error and return it, as opposed to propagating an error generated by a lower procedure, you should use: + + +.. code-block:: c + + return_error(error_number); + + +Sometimes it is more convenient to generate the error in one place and return it in another. In this case, you should use: + + +.. code-block:: c + + code = gs_note_error(error_number); + ... + return code; + +In executables built for debugging, the ``-E`` (or ``-Z#``) command line switch causes ``return_error`` and ``gs_note_error`` to print the error number and the source file and line: this is often helpful for identifying the original cause of an error. + +See the file ``base/gserrors.h`` for the error return codes used by the graphics library, most of which correspond directly to PostScript error conditions. + + + + + + + + +.. include:: footer.rst + + + + + + + + + + + + + + + + + + + + diff --git a/doc/src/Develop.rst b/doc/src/Develop.rst new file mode 100644 index 00000000..97131f2e --- /dev/null +++ b/doc/src/Develop.rst @@ -0,0 +1,1650 @@ +.. title:: Information for Ghostscript Developers + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Develop.htm: +.. _Ghostscript Developers: + + +Information for Ghostscript Developers +====================================== + + +Introduction +------------------------------------ +This document provides a wealth of information about Ghostscript's internals, primarily for developers actively working on Ghostscript. It is primarily **descriptive**, documenting the way things are; the companion :ref:`C style guide<C-style.htm>` is primarily **prescriptive**, documenting what developers should do when writing new code. + + +Architecture +------------------------------------ + + + +Design Goals +~~~~~~~~~~~~~~~ +Ghostscript has the following high-level design goals (not listed in order +of importance): + +Functionality +"""""""""""""""" + + - Ability to interpret the current PostScript and PDF languages, as defined (and occasionally, in the case of conflict, as implemented) by Adobe. + + - Ability to convert PostScript to and from PDF, comparable to Adobe products. + + - 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). + +Performance +"""""""""""""""" + + - Ability to render PostScript and PDF with commercial-quality performance (memory usage, speed, and output quality) on all platforms. + + - Specifically, ability to render PostScript effectively in embedded environments with constrained RAM, including the ability to put the code and supporting data in ROM. + +Licensing +"""""""""""""""" + + - Licensing that supports both the Open Source / Free software communities and a commercial licensing business. + + - Freedom from licensing restrictions or fees imposed by third parties. + +Other +"""""""""""""""" + + - Easy source portability to any platform (CPU, operating system, and development tools) that has an ANSI C compiler. + + - 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. + + +These goals often conflict: part of Ghostscript's claim to quality is that the conflicts have been resolved well. + + + +Design principles +------------------------ + +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. + +Non-preemption +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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. + +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 return, preserving its own state in data structures, or to call back 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: + +- For callers that want to pass input to Ghostscript piece by piece, Ghostscript returns with an ``gs_error_NeedInput`` 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). + +- In the future, the same arrangement should be used for input from ``stdin`` and output to ``stdout`` and ``stderr``. + +- 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. + +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.) + + +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 `Memory management`_ section below. + +Multi-instantiability +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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. + +Late configuration binding +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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. + +- 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. +- 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). +- Startup binds essentially nothing. Almost every option and parameter that can appear on the command line can also be changed dynamically. +- 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. + + +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. + + +Large-scale structure +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +At the largest design scale, Ghostscript consists of 4 layers. Layer N is allowed to use the facilities of all layers M <= N. + +#. The bottom layer is called the substrate. 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. + +#. The layer above the substrate is the graphics layer. It consists of two separate sub-parts. The graphics layer is written in C. + + - The graphics library 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. + + - The device drivers 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. + +#. The principal clients of the graphics layer are language interpreters. Ghostscript as distributed includes the PostScript interpreter; 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. + +#. The PDF interpreter is actually a client of the PostScript interpreter: it is written entirely in PostScript. + +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 :ref:`Drivers<Drivers.htm>`) and kept stringently backward-compatible through successive releases. + + +Object-oriented constructs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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 :ref:`"Objects"<CStyle_Objects>` section of the :ref:`C style guide<C-style.htm>` explains these. + +The memory manager API provides run-time type information about each class, but this information does not include anything about subclassing. See under :ref:`Structure descriptors<Develop_Structure_Descriptors>` below. + + + + + + +File roadmap +---------------------- + + +This section of the document provides a roadmap to all of the Ghostscript source files. + +Substrate +~~~~~~~~~~~~~~ + +Runtime Context +"""""""""""""""""""" + +The ``libctx`` provides pointers to memory, ``stdio``, and various other runtime portablility services: + base/gslibctx.h, base/gslibctx.c + +Memory manager +"""""""""""""""""""" + +See `Memory Management`_ + +Streams +"""""""""""""""""""" + +Framework, file and string streams: + base/gsdsrc.c, base/gsdsrc.h, base/scommon.h, base/strmio.c, base/strmio.h, base/sfxboth.c, base/sfxfd.c, base/sfxstdio.c, base/sfxcommon.c, base/stream.h, base/stream.c, base/strimpl.h. + + +Standard filters: + + CCITTFax: + base/scf.h, base/scfd.c, base/scfdgen.c, base/scfdtab.c, base/scfe.c, base/scfetab.c, base/scfparam.c, base/scfx.h. + + DCT (JPEG): + base/gsjconf.h, base/gsjmorec.h, base/sdcparam.c, base/sdcparam.h, base/sdct.h, base/sdctc.c, base/sdctd.c, base/sdcte.c, base/sddparam.c, base/sdeparam.c, base/sjpeg.h, base/sjpegc.c, base/sjpegd.c, base/sjpege.c. + + JBIG2: + base/sjbig2.h, base/sjbig2.c + + JPX (JPEG 2000): + base/sjpx_openjpeg.h, base/sjpx_openjpeg.c + + Other compression/decompression: + base/slzwc.c, base/slzwd.c, base/slzwe.c, base/slzwx.h, base/srld.c, base/srle.c, base/srlx.h. + + Other: + base/sa85d.c, base/sa85d.h, base/sa85x.h, psi/sfilter1.c, base/sfilter2.c, base/sstring.c, base/sstring.h. + + + +Non-standard filters used to implement standard filters: + base/seexec.c, base/sfilter.h, base/shc.c, base/shc.h, base/spdiff.c, base/spdiffx.h, base/spngp.c, base/spngpx.h, base/szlibc.c, base/szlibd.c, base/szlibe.c, base/szlibx.h, base/szlibxx.h. + +Non-standard filters: + base/sbcp.c, base/sbcp.h, base/sbtx.h, base/smd5.c, base/smd5.h, base/saes.c, base/saes.h, base/sarc4.c, base/sarc4.h, + +Internal filters: + base/siinterp.c, base/siinterp.h, base/siscale.c, base/siscale.h, base/sidscale.c, base/sidscale.h, base/sisparam.h. + +Higher-level stream support: + base/spprint.c, base/spprint.h, base/spsdf.c, base/spsdf.h, base/srdline.h. + + +Platform-specific code +"""""""""""""""""""""""""""""""""""""""" + +See `Cross-platform APIs`_. + +Miscellaneous +"""""""""""""""""""""""""""""""""""""""" + +Library top level: + base/gsinit.c, base/gslib.h. + +Configuration-related: + base/gconf.c, base/gconf.h, base/gscdef.c, base/gscdefs.h, base/gsromfs0.c. + +Arithmetic: + base/gxarith.h, base/gxdda.h, base/gxfarith.h, base/gxfixed.h, base/gxfrac.h. + +Operating system interface: + base/gserrors.h, base/gsexit.h, base/gxstdio.h, base/gxsync.c, base/gxsync.h. + +Other: + base/gsargs.c, base/gsargs.h, base/gserrors.h, base/gsnotify.c, base/gsnotify.h, base/gsrect.h, base/gstypes.h, base/gsuid.h, base/gsutil.h, base/gsutil.c, base/gx.h, base/gsmd5.c, base/gsmd5.h, base/aes.c, base/aes.h. + + +Graphics library +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. _Graphics library_Support: + +Support +"""""""""" + +Bitmap processing: + base/gsbitcom.c, base/gsbitmap.h, base/gsbitops.c, base/gsbitops.h, base/gsbittab.c, base/gsbittab.h, base/gsflip.c, base/gsflip.h, base/gxbitmap.h, base/gxbitops.h, base/gxsample.c, base/gxsample.h. base/gxsamplp.h. + +Functions: + base/gsfunc.c, base/gsfunc.h, base/gsfunc0.c, base/gsfunc0.h, base/gsfunc3.c, base/gsfunc3.h, base/gsfunc4.c, base/gsfunc4.h, base/gxfunc.h. + +Parameter lists: + base/gscparam.c, base/gsparam.c, base/gsparam.h, base/gsparam2.c (not used), base/gsparams.c, base/gsparams.h, base/gsparamx.c, base/gsparamx.h. + +I/O-related: + base/gdevpipe.c, base/gsfname.c, base/gsfname.h, base/gsio.h, base/gsiodev.c, base/gsiodevs.c, base/gsiodisk.c, base/gsiorom.c. base/gsiorom.h. base/gxiodev.h. + + +Paths +"""""""""" + +Coordinate transformation: + base/gscoord.c, base/gscoord.h, base/gsmatrix.c, base/gsmatrix.h, base/gxcoord.h, base/gxmatrix.h. + +Path building: + base/gsdps1.c, base/gspath.c, base/gspath.h, base/gspath1.c, base/gspath2.h, base/gxpath.c, base/gxpath.h, base/gxpath2.c, base/gxpcopy.c, base/gxpdash.c, base/gxpflat.c, base/gzpath.h. + +Path rendering: + base/gdevddrw.c, base/gdevddrw.h, base/gxdtfill.h, base/gsdps1.c, base/gspaint.c, base/gspaint.h, base/gspenum.h, base/gxfill.c, base/gxfill.h, base/gxfillsl.h, base/gxfilltr.h, base/gxfillts.h, base/gximask.c, base/gximask.h, base/gxfdrop.c, base/gxfdrop.h, base/gxpaint.c, base/gxpaint.h, base/gxstroke.c, base/gzspotan.c, base/gzspotan.h. + +Clipping: + See under `Clipping`_ below. + +Text +"""""""""" + +Fonts, generic: + base/gsfont.c, base/gsfont.h, devices/gxfcopy.c, devices/gxfcopy.h, base/gxfont.h. + +Fonts, specific FontTypes: + base/gsfcid.c, base/gsfcid.c, base/gsfcmap.c, base/gsfcmap1.c, base/gsfcmap.h, base/gsfont0.c, base/gsfont0c.c, base/gxcid.h, base/gxfcid.h, base/gxfcmap.h, base/gxfcmap1.h, base/gxfont0.h, base/gxfont0c.h, base/gxfont1.h, base/gxfont42.h, base/gxftype.h, base/gxttf.h. + +Character rendering + font cache, generic: + base/gsccode.h, base/gschar.c, base/gschar.h, base/gscpm.h, base/gsgdata.c, base/gsgdata.h, base/gsgcache.c, base/gsgcache.h, base/gstext.c, base/gstext.h, base/gxbcache.c, base/gxbcache.h, base/gxccache.c, base/gxccman.c, base/gxchar.c, base/gxchar.h, base/gxfcache.h, base/gxtext.h. + +Character rendering, specific FontTypes: + base/gschar0.c, base/gscrypt1.c, base/gscrypt1.h, base/gstype1.c, base/gstype1.h, base/gstype2.c, base/gstype42.c, base/gxchrout.c, base/gxchrout.h, base/gxhintn.h, base/gxhintn.c, base/gxhintn1.c, base/gxtype1.c, base/gxtype1.h. + + +Images +"""""""""" + +Buffered API (mostly for PostScript interpreter): + base/gsimage.c, base/gsimage.h. + +Generic support: + base/gsiparam.h, base/gxiclass.h, base/gximage.c, base/gximage.h, base/gxiparam.h. + +Type 1 and 4 images: + + Setup: + base/gsiparm4.h, base/gximage1.c, base/gximage4.c. + + Rendering: + base/gxi12bit.c, base/gxi16bit.c, base/gxicolor.c, base/gxidata.c, base/gxifast.c, base/gximono.c, base/gxino12b.c, base/gxino16b.c, base/gxipixel.c, base/gxiscale.c. + +Type 2 images (Display PostScript): + base/gsiparm2.h, base/gximage2.c. + +Type 3 images: + base/gsipar3x.h, base/gsiparm3.h, base/gximag3x.c, base/gximag3x.h, base/gximage3.c, base/gximage3.h. + +Other: + base/gsimpath.c, base/simscale.c, base/simscale.h. + +Paint +"""""""""" + +Ghostscript uses 4 internal representations of color. We list them here in the order in which they occur in the rendering pipeline. + +#. Clients of the graphics library normally specify colors using the client color structure (``gs_client_color``, defined in psi/gs.color.h), consisting of one or more numeric values and/or a pointer to a Pattern instance. This corresponds directly to the values that would be passed to the PostScript setcolor operator: one or more (floating-point) numeric components and/or a Pattern. Client colors are interpreted relative to a color space (``gs_color_space``, defined in base/gscspace.h and base/gxcspace.h, with specific color spaces defined in other files). Client colors do not explicitly reference the color space in which they are are interpreted: setcolor uses the color space in the graphics state, while images and shadings explicitly specify the color space to be used. + +#. For ordinary non-Pattern colors, the first step in color rendering reduces a client color to a concrete color -- a set of values in a color space that corresponds to the device's color model (except for possible conversions between DeviceGray, DeviceRGB, and DeviceCMYK), together with an identification of the associated color space. (The confusion here between color spaces and color models will have to be cleaned up when we implement native Separation/DeviceN colors.) Concrete colors are like the numeric values in a client color, except that they are represented by arrays of ``frac`` values (defined in base/gxfrac.h) rather than floats. The procedure for this step is the virtual ``concretize_color`` and ``concrete_space`` procedures in the (original) color space. This step reduces Indexed colors, CIEBased colors, and Separation and DeviceN colors that use the alternate space. + +#. The final step requires mapping a concrete color to the device's color model, done by procedures in base/gxcmap.c. These procedures combine the following three conceptual sub-steps: + + - A possible mapping between Device color spaces, possibly involving black generation and undercolor removal. The non-trivial cases are implemented in base/gxdcconv.c. + + - Application of the transfer function(s) (done in-line). + + - Halftoning if necessary: see below. + + The result is called (inappropriately) a device color (``gx_device_color``, defined in psi/gs.color.h and base/gxdcolor.h). For ordinary non-Pattern colors, a device color is either a pure color, or a halftone. The device and color model associated with a device color are implicit. The procedure for this step is the virtual ``remap_concrete_color`` procedure in the color space. + +#. The pure colors that underlie a device color are opaque pixel values defined by the device (misnamed ``gx_color_index``, defined in base/gscindex.h). The device with which they are associated is implicit. Although the format and interpretation of a pixel value are known only to the device, the device's color model and color representation capabilities are public, defined by a ``gx_color_info`` structure stored in the device (defined in base/gxdevcli.h). Virtual procedures of the device driver map between pixel values and RGB or CMYK. (This area is untidy and will need to be cleaned up when we implement native Separation/DeviceN colors). + + +Steps 2 and 3 are normally combined into a single step for efficiency, as the ``remap_color`` virtual procedure in a color space. + +Using a device color to actually paint pixels requires a further step called color loading, implemented by the load virtual procedure in the device color. This does nothing for pure colors, but loads the caches for halftones and Patterns. + +All of the above steps -- concretizing, mapping to a device color, and color loading -- are done as late as possible, normally not until the color is actually needed for painting. + +All painting operations (fill, stroke, imagemask/show) eventually call a virtual procedure in the device color, either ``fill_rectangle`` or ``fill_mask`` to actually paint pixels. For rectangle fills, pure colors call the device's fill_rectangle procedure; halftones and tiled Patterns call the device's ``strip_tile_rectangle``; shaded Patterns, and painting operations that involve a RasterOp, do something more complicated. + +Color specification: + base/gsdcolor.h, base/gscolor.c, base/gscolor.h, base/gscolor1.c, base/gscolor1.h, base/gscolor2.c, base/gscolor2.h, base/gscolor3.c, base/gscolor3.h, base/gshsb.c, base/gshsb.h, base/gxcolor2.h, base/gxcvalue.h. + +Color spaces: + base/gscdevn.c, base/gscdevn.h, base/gscie.c, base/gscie.h, base/gscpixel.c, base/gscpixel.h, base/gscscie.c, base/gscsepr.c, base/gscsepr.h, base/gscspace.c, base/gscspace.h, base/gscssub.c, base/gscssub.h, base/gxcdevn.h, base/gxcie.h, base/gxcspace.h. + +Color mapping: + base/gsciemap.c, base/gscindex.h, base/gscrd.c, base/gscrd.h, base/gscrdp.c, base/gscrdp.h, base/gscsel.h, base/gxcindex.h, base/gxcmap.c, base/gxcmap.h, base/gxctable.c, base/gxctable.h, base/gxdcconv.c, base/gxdcconv.h, base/gxdcolor.c, base/gxdcolor.h, base/gxdevndi.c, base/gxdevndi.h, base/gxdither.h, base/gxfmap.h, base/gxlum.h, base/gxtmap.h. + + + ICC profiles are in some ways a special case of color mapping, but are not standard in PostScript. + + base/gsicc.c, base/gsicc.h, + + The following files provide a callback mechanism to allow a client program to specify a special case alternate tint transforms for Separation and DeviceN color spaces. Among other uses this can be used to provide special handling for PANTONE colors. + + base/gsnamecl.c, base/gsnamecl.h, base/gsncdummy.c, base/gsncdummy.h, psi/zncdummy.c + + +Ghostscript represents halftones internally by "whitening orders" -- essentially, arrays of arrays of bit coordinates within a halftone cell, specifying which bits are inverted to get from halftone level K to level K+1. The code does support all of the PostScript halftone types, but they are all ultimately reduced to whitening orders. + +Threshold arrays, the more conventional representation of halftones, can be mapped to whitening orders straightforwardly; however, whitening orders can represent non-monotonic halftones (halftones where the bits turned on for level K+1 don't necessarily include all the bits turned on for level K), while threshold arrays cannot. On the other hand, threshold arrays allow rapid conversion of images (using a threshold comparison for each pixel) with no additional space, while whitening orders do not: they require storing the rendered halftone cell for each possible level as a bitmap. + +Ghostscript uses two distinct types of rendered halftones -- that is, the bitmap(s) that represent a particular level. + +- Binary halftones. The rendered halftone is a single bit plane; each bit selects one of two pure colors. These are fast but limited: they are used for monochrome output devices, or for color devices in those cases where only two distinct colors are involved in a halftone (e.g., a pure cyan shade on a CMYK device). The device color for a binary halftone stores a pointer to the halftone bitmap, and the two pure colors. + +- Multi-plane halftones. Internally, each plane is rendered individually. Since there isn't enough room to store all 2^N pure colors, multi-plane halftones only store the scaled values for the individual components; the halftone renderer maps these to the pure colors on the fly, then combines the planes to assemble an N-bit index into the list of colors for each pixel, and stores the color into the fully rendered halftone. + + +The halftone level for rendering a color is computed in base/gxdevndi.c; the actual halftone mask or tile is computed either in base/gxcht.c (for multi-plane halftones), or in base/gxht.c and base/gxhtbit.c (for binary halftones). + +Halftoning: + base/gsht.c, base/gsht.h, base/gsht1.c, base/gsht1.h, base/gshtscr.c, base/gshtx.c, base/gshtx.h, base/gxcht.c, base/gxdht.h, base/gxdhtres.h, base/gxht.c, base/gxht.h, base/gxhtbit.c, base/gxhttile.h, base/gxhttype.h, base/gzht.h. + + +Pattern colors (tiled patterns and shadings) each use a slightly different approach from solid colors. + +The device color for a tiled (PatternType 1) pattern contains a pointer to a pattern instance, plus (for uncolored patterns) the device color to be masked. The pattern instance includes a procedure that actually paints the pattern if the pattern is not in the cache. For the PostScript interpreter, this procedure returns an ``gs_error_RemapColor`` exception code: this eventually causes the interpreter to run the pattern's PaintProc, loading the rendering into the cache, and then re-execute the original drawing operator. + +Patterns: + base/gs.color.c, base/gs.color.h, base/gsptype1.c, base/gsptype1.h, base/gxp1fill.c, base/gxp1impl.h, base/gxpcache.h, base/gxpcmap.c, base/gxpcolor.h. + + +The device color for a shading (PatternType 2) pattern also contains a pointer to a pattern instance. Shadings are not cached: painting with a shading runs the shading algorithm every time. + +Shading: + base/gsptype2.c, base/gsptype2.h, base/gsshade.c, base/gsshade.h, base/gxshade.c, base/gxshade.h, base/gxshade1.c, base/gxshade4.c, base/gxshade4.h, base/gxshade6.c, base/gscicach.h, base/gscicach.c. + + +In addition to the PostScript graphics model, Ghostscript supports RasterOp, a weak form of alpha channel, and eventually the full PDF 1.4 transparency model. The implemention of these facilities is quite slipshod and scattered: only RasterOp is really implemented fully. There is a general compositing architecture, but it is hardly used at all, and in particular is not used for RasterOp. It is used for implementation of the general support for overprint and overprint mode. + +Compositing architecture: + base/gscompt.h, base/gxcomp.h. + +RasterOp: + base/gdevdrop.c, base/gdevrops.c, base/gsrop.c, base/gsrop.h, base/gsropt.h, base/gsroptab.c, base/gxdevrop.h. + +Alpha channel and compositing: + base/gsalpha.c, base/gsalpha.h, base/gsdpnext.h, base/gxalpha.h. + +Advanced transparency: + base/gstparam.h, base/gstrans.c, base/gstrans.h, base/gxblend.c, base/gxblend.h, base/gdevp14.c, base/gdevp14.h. + +Overprint and Overprint mode: + base/gsovrc.c, base/gsovrc.h, base/gxoprect.c, base/gxoprect.h. There is support for both overprint and overprint mode. There is a general compositor based implementation of these features for all devices. In addition, the memory devices implement a higher speed set of special fill routines to improve performance for printer based devices. + + +Clipping +"""""""""" + +The Ghostscript graphics library implements clipping by inserting a clipping device in the device pipeline. The clipping device modifies all drawing operations to confine them to the clipping region. + +The library supports three different kinds of clipping: + +- Region/path clipping + This corresponds to the PostScript concept of a clipping path. The clipping region is specified either by a list of rectangles (subject to the constraints documented in base/gxcpath.h), or by a path that is converted to such a list of rectangles. + +- Stationary mask clipping + This corresponds to the mask operand of a PostScript ImageType 3 image. The clipping region is specified by a bitmap and an (X,Y) offset in the coordinate space. + +- Tiled mask clipping + This corresponds to the region painted by a PostScript Pattern, for the case where the Pattern does not completely cover its bounding box but the combined transformation matrix has no skew or non-orthogonal rotation (i.e., XStep and YStep map respectively to (X,0) and (0,Y) or vice versa). The clipping region is specified by a bitmap and an (X,Y) offset in the coordinate space, and is replicated indefinitely in both X and Y. + + +Note that simply scan-converting a clipping path in the usual way does not produce a succession of rectangles that can simply be stored as the list for region-based clipping: in general, the rectangles do not satisfy the constraint for rectangle lists specified in base/gxcpath.h, since they may overlap in X, Y, or both. A non-trivial "clipping list accumulator" device is needed to produce a rectangle list that does satisfy the constraint. + +Clipping support: + base/gxclip.c, base/gxclip.h. + +Region/path clipping: + base/gxcpath.c, base/gxcpath.h, base/gzcpath.h. + +Clipping list accumulator: + base/gxacpath.c, base/gzacpath.h. + +Mask clipping support: + base/gxmclip.c, base/gxmclip.h. + +Stationary mask clipping: + base/gxclipm.c, base/gxclipm.h. + +Tiled mask clipping: + base/gxclip2.c, base/gxclip2.h. + + +Other graphics +"""""""""""""""""""" + +Miscellaneous graphics state: + base/gsclipsr.c, base/gsclipsr.h, base/gsdps.c, base/gsdps.h, base/gsdps1.c, base/gsistate.c, base/gsline.c, base/gsline.h, base/gslparam.h, base/gsstate.c, base/gsstate.h, base/gstrap.c, base/gstrap.h, base/gxclipsr.h, base/gxistate.h, base/gxline.h, base/gxstate.h, base/gzline.h, base/gzstate.h. + + +Font API support +"""""""""""""""""""" + +UFST bridge: + base/gxfapiu.c, base/gxfapiu.h. + + +Driver support +"""""""""""""""""""" + +Generic driver support: + base/gdevdcrd.c, base/gdevdcrd.h, base/gdevdsha.c, base/gdevemap.c, base/gsdevice.c, base/gsdevice.h, base/gsdparam.c, base/gsxfont.h, base/gxdevbuf.h, base/gxdevcli.h, base/gxdevice.h, base/gxrplane.h, base/gxxfont.h. + +Accessing rendered bits: + base/gdevdbit.c, base/gdevdgbr.c, base/gxbitfmt.h, base/gxgetbit.h. + +"Printer" driver support: + devices/gdevmeds.c, devices/gdevmeds.h, base/gdevppla.c, base/gdevppla.h, base/gdevprn.c, base/gdevprn.h, base/gdevprna.c, base/gdevprna.h, base/gxband.h, base/gxpageq.c, base/gxpageq.h. + +High-level device support: + base/gdevvec.c, base/gdevvec.h, base/gxhldevc.c, base/gxhldevc.h. + +Banding: + base/gxclbits.c, base/gxcldev.h, base/gxclfile.c, base/gxclimag.c, base/gxclio.h, base/gxclist.c, base/gxclist.h, base/gxcllzw.c, base/gxclmem.c, base/gxclmem.h, base/gxclpage.c, base/gxclpage.h, base/gxclpath.c, base/gxclpath.h, base/gxclrast.c, base/gxclread.c, base/gxclrect.c, base/gxclthrd.c, base/gxclthrd.h, base/gxclutil.c, base/gxclzlib.c, base/gxdhtserial.c, base/gxdhtserial.h, base/gsserial.c, base/gsserial.h. + + +Visual Trace +"""""""""""""""""""" + +Visual Trace support : + base/vdtrace.h, base/vdtrace.c. + + +See :ref:`Visual Trace instructions<Lib_VisualTrace>` for extensive documentation. + + +Device drivers +~~~~~~~~~~~~~~~~~~~~ + +See :ref:`Drivers<Drivers.htm>` for extensive documentation on the interface between the core code and drivers. + +The driver API includes high-level (path / image / text), mid-level (polygon), and low-level (rectangle / raster) operations. Most devices implement only the low-level operations, and let generic code break down the high-level operations. However, some devices produce high-level output, and therefore must implement the high-level operations. + +Internal devices +"""""""""""""""""""" + +There are a number of "devices" that serve internal purposes. Some of these are meant to be real rendering targets; others are intended for use in device pipelines. The rendering targets are: + +Memory devices, depth-independent: + base/gdevmem.c, base/gdevmem.h, base/gdevmpla.c, base/gdevmpla.h, base/gdevmrop.h, base/gsdevmem.c, base/gxdevmem.h. + +Memory devices, specific depths: + base/gdevm1.c, base/gdevm2.c, base/gdevm4.c, base/gdevm8.c, base/gdevm16.c, base/gdevm24.c, base/gdevm32.c, base/gdevm40.c, base/gdevm48.c, base/gdevm56.c, base/gdevm64.c, base/gdevmr1.c, base/gdevmr2n.c, base/gdevmr8n.c. + +Alpha-related devices: + base/gdevabuf.c. + +Other devices: + base/gdevdflt.c, base/gdevhit.c, base/gdevmrun.c, base/gdevmrun.h, base/gdevplnx.c, base/gdevplnx.h. + + +The forwarding devices meant for use in pipelines are: + +The bounding box device: + base/gdevbbox.h, base/gdevbbox.c. + +Clipping devices: + See under Clipping_ above. + +Other devices: + base/gdevnfwd.c. + + +PostScript and PDF writers +""""""""""""""""""""""""""""""""""""" + +Because PostScript and PDF have the same graphics model, lexical syntax, and stack-based execution model, the drivers that produce PostScript and PDF output share a significant amount of support code. In the future, the PostScript output driver should be replaced with a slightly modified version of the PDF driver, since the latter is far more sophisticated (in particular, it has extensive facilities for image compression and for handling text and fonts). + +The PDF code for handling text and fonts is complex and fragile. A major rewrite in June 2002 was intended to make it more robust and somewhat easier to understand, but also increased its size by about 40%, contrary to the expectation that it would shrink. Currently both sets of code are in the code base, with compatible APIs, selected by a line in ``devices/devs.mak``. + + +Shared support +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Writing fonts: + devices/vector/gdevpsf.h, devices/vector/gdevpsf1.c, devices/vector/gdevpsf2.c, devices/vector/gdevpsfm.c, devices/vector/gdevpsft.c, devices/vector/gdevpsfu.c, devices/vector/gdevpsfx.c, base/gscedata.c, base/gscedata.h, base/gscencs.c, base/gscencs.h. + +Other: + devices/vector/gdevpsdf.h, devices/vector/gdevpsdi.c, devices/vector/gdevpsdp.c, devices/vector/gdevpsds.c, devices/vector/gdevpsds.h, devices/vector/gdevpsdu.c. + +Encapsulated PostScript output driver (epswrite): + devices/vector/gdevpsu.c, devices/vector/gdevpsu.h. + +PDF output driver (pdfwrite) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Substrate: + devices/vector/gdevpdfo.c, devices/vector/gdevpdfo.h, devices/vector/gdevpdfr.c, devices/vector/gdevpdfu.c. + +Old text and fonts: + devices/vector/gdevpdfe.c, devices/vector/gdevpdft.c. + +New text and fonts: + devices/vector/gdevpdt.c, devices/vector/gdevpdt.h, devices/vector/gdevpdtb.c, devices/vector/gdevpdtb.h, devices/vector/gdevpdtc.c, devices/vector/gdevpdtd.c, devices/vector/gdevpdtd.h, devices/vector/gdevpdte.c, devices/vector/gdevpdtf.c, devices/vector/gdevpdtf.h, devices/vector/gdevpdti.c, devices/vector/gdevpdti.h, devices/vector/gdevpdts.c, devices/vector/gdevpdts.h, devices/vector/gdevpdtt.c, devices/vector/gdevpdtt.h, devices/vector/gdevpdtv.c, devices/vector/gdevpdtv.h, devices/vector/gdevpdtw.c, devices/vector/gdevpdtw.h, devices/vector/gdevpdtx.h. base/ConvertUTF.h, base/ConvertUTF.c, + +Graphics: + devices/vector/gdevpdfc.c, devices/vector/gdevpdfc.h, devices/vector/gdevpdfd.c, devices/vector/gdevpdfg.c, devices/vector/gdevpdfg.h, devices/vector/gdevpdfk.c, devices/vector/gdevpdft.c. devices/vector/gdevpdfv.c. + +Images: + devices/vector/gdevpdfb.c, devices/vector/gdevpdfi.c, devices/vector/gdevpdfj.c. + +Other: + devices/vector/gdevpdf.c, devices/vector/gdevpdfm.c, devices/vector/gdevpdfp.c, devices/vector/gdevpdfx.h. devices/vector/gdevpdfb.h. + +Other high-level devices +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +PCL XL output device (pxlmono, pxlcolor): + devices/vector/gdevpx.c, base/gdevpxat.h, base/gdevpxen.h, base/gdevpxop.h, devices/gdevpxut.c, devices/gdevpxut.h. + +Text extraction: + devices/vector/gdevtxtw.c. + +Other: + devices/gdevtrac.c. + +Other maintained drivers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The standard Ghostscript distribution includes a collection of drivers, mostly written by Aladdin Enterprises, that are "maintained" in the same sense as the Ghostscript core code. + +Display drivers: + devices/gdev8bcm.c, devices/gdev8bcm.h, devices/gdevevga.c, devices/gdevl256.c, base/gdevpccm.c, base/gdevpccm.h, devices/gdevpcfb.c, devices/gdevpcfb.h, devices/gdevs3ga.c, devices/gdevsco.c, devices/gdevsvga.c, devices/gdevsvga.h, devices/gdevvglb.c. + +Window system drivers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +X Windows: + devices/gdevx.c, devices/gdevx.h, devices/gdevxalt.c, devices/gdevxcmp.c, devices/gdevxcmp.h, devices/gdevxini.c, devices/gdevxres.c. + +Microsoft Windows: + devices/gdevmswn.c, devices/gdevmswn.h, devices/gdevmsxf.c, devices/gdevwddb.c, devices/gdevwdib.c. + +OS/2 Presentation Manager: + devices/gdevpm.h, base/gspmdrv.c, base/gspmdrv.h. + + + +Raster file output drivers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Fax and TIFF: + devices/gdevfax.c, devices/gdevfax.h, devices/gdevtfax.c, devices/gdevtfax.h, devices/gdevtifs.c, devices/gdevtifs.h, devices/gdevtfnx.c. devices/gdevtsep.c. + +Example DeviceN devices: + base/gdevdevn.c, base/gdevdevn.h, devices/gdevxcf.c, devices/gdevpsd.c, devices/gdevperm.c. + +Other raster file formats: + devices/gdevbit.c, devices/gdevbmp.c, devices/gdevbmp.h, devices/gdevbmpa.c, devices/gdevbmpc.c, devices/gdevjpeg.c, devices/gdevmiff.c, devices/gdevp2up.c, devices/gdevpcx.c, devices/gdevpbm.c, devices/gdevpng.c, devices/gdevpsim.c. + + +Printer drivers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Operating system printer services: + devices/gdevos2p.c, devices/gdevwpr2.c, devices/gdevwprn.c. + +H-P monochrome printers: + devices/gdevdljm.c, devices/gdevdljm.h, devices/gdevdjet.c, devices/gdevlj56.c. + +Other printers: + devices/gdevatx.c. + + +Contributed drivers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This list is likely to be incomplete and inaccurate: see devices/contrib.mak and contrib/contrib.mak. + +Display and window system drivers: + devices/gdev3b1.c, devices/gdevherc.c, devices/gdevpe.c, devices/gdevsnfb.c, devices/gdevsun.c. + +Raster file output drivers: + devices/gdevcfax.c, devices/gdevcif.c, devices/gdevdfax.c, devices/gdevifno.c, devices/gdevmgr.c, devices/gdevmgr.h, devices/gdevsgi.c, devices/gdevsgi.h, devices/gdevsunr.c, devices/gdevjbig2.c, devices/gdevjpx.c. + +Printer drivers: + lib/bj8.rpd, lib/cbjc600.ppd, lib/cbjc800.ppd, devices/gdev3852.c, devices/gdev4081.c, devices/gdev4693.c, devices/gdev8510.c, devices/gdevadmp.c, devices/gdevbj10.c, devices/gdevbjc.h, devices/gdevbjcl.c, devices/gdevbjcl.h, devices/gdevccr.c, devices/gdevcdj.c, devices/gdevclj.c, devices/gdevcljc.c, devices/gdevcslw.c, devices/gdevdjtc.c, devices/gdevdm24.c, devices/gdevepsc.c, devices/gdevepsn.c, devices/gdevescp.c, devices/gdevhl7x.c, devices/gdevijs.c, devices/gdevimgn.c, devices/gdevl31s.c, devices/gdevlbp8.c, devices/gdevlp8k.c, devices/gdevlxm.c, devices/gdevn533.c, devices/gdevo182.c, devices/gdevokii.c, devices/gdevpcl.c, devices/gdevpcl.h, devices/gdevphex.c, devices/gdevpjet.c, devices/gdevsj48.c, devices/gdevsppr.c, devices/gdevstc.c, devices/gdevstc.h, devices/gdevstc1.c, devices/gdevstc2.c, devices/gdevstc3.c, devices/gdevstc4.c, devices/gdevtknk.c, devices/gdevupd.c. + +The special rinkj high-quality inkjet driver: + devices/gdevrinkj.c, base/gsequivc.c, base/gsequivc.h, devices/rinkj/evenbetter-rll.c, devices/rinkj/evenbetter-rll.h, devices/rinkj/rinkj-byte-stream.c, devices/rinkj/rinkj-byte-stream.h, devices/rinkj/rinkj-config.c, devices/rinkj/rinkj-config.h, devices/rinkj/rinkj-device.c, devices/rinkj/rinkj-device.h, devices/rinkj/rinkj-dither.c, devices/rinkj/rinkj-dither.h, devices/rinkj/rinkj-epson870.c, devices/rinkj/rinkj-epson870.h, devices/rinkj/rinkj-screen-eb.c, devices/rinkj/rinkj-screen-eb.h, lib/rinkj-2200-setup. + + +PostScript interpreter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PostScript interpreter is conceptually simple: in fact, an interpreter that could execute "3 4 add =" and print "7" was running 3 weeks after the first line of Ghostscript code was written. However, a number of considerations make the code large and complex. + +The interpreter is designed to run in environments with very limited memory. The main consequence of this is that it cannot allocate its stacks (dictionary, execution, operand) as ordinary arrays, since the user-specified stack size limit may be very large. Instead, it allocates them as a linked list of blocks. See below for more details. + +The interpreter must never cause a C runtime error that it cannot trap. Unfortunately, C implementations almost never provide the ability to trap stack overflow. In order to put a fixed bound on the C stack size, the interpreter never implements PostScript recursion by C recursion. This means that any C code that logically needs to call the interpreter must instead push a continuation (including all necessary state information) on the PostScript execution stack, followed by the PostScript object to be executed, and then return to the interpreter. (See psi/estack.h for more details about continuations.) Unfortunately, since PostScript Level 2 introduces streams whose data source can be a PostScript procedure, any code that reads or writes stream data must be prepared to suspend itself, storing all necessary state in a continuation. There are some places where this is extremely awkward, such as the scanner/parser. + +The use of continuations affects many places in the interpreter, and even some places in the graphics library. For example, when processing an image, one may need to call a PostScript procedure as part of mapping a CIE color to a device color. Ghostscript uses a variety of dodges to handle this: for example, in the case of CIE color mapping, all of the PostScript procedures are pre-sampled and the results cached. The Adobe implementation limits this kind of recursion to a fixed number of levels (5?): this would be another acceptable approach, but at this point it would require far more code restructuring than it would be worth. + +A significant amount of the PostScript language implementation is in fact written in PostScript. Writing in PostScript leverages the C code for multi-threading, garbage collection, error handling, continuations for streams, etc., etc.; also, we have found PostScript in general more concise and easier to debug than C, mostly because of memory management issues. So given the choice, we tended to implement a feature in PostScript if it worked primarily with PostScript data structures, wasn't heavily used (example: font loading), or if it interacted with the stream or other callback machinery (examples: ReusableFileDecode streams, resourceforall). Often we would add non-standard PostScript operators for functions that had to run faster or that did more C-like things, such as the media matching algorithm for setpagedevice. + +Main program +""""""""""""""""""""""" + +The main program of the interpreter is normally invoked from the command line, but it has an API as well. In fact, it has two APIs: one that recognizes the existence of multiple "interpreter instances" (although it currently provides a default instance, which almost all clients use), and a completely different one designed for Windows DLLs. These should be unified as soon as possible, since there are two steadily growing incompatible bodies of client code. + +Files: + psi/gs.c, psi/gserver.c, psi/iinit.c, psi/iinit.h, psi/imain.c, psi/imain.h, psi/imainarg.c, psi/imainarg.h, psi/iminst.h, psi/main.h. + + +Data structures +""""""""""""""""""""""" + +The main data structures visible to the PostScript programmers are arrays, contexts, dictionaries, names, and stacks. + +Arrays have no unusual properties. See under Refs below for more information about how array elements are stored. + +Contexts are used to hold the interpreter state even in configurations that don't include the Display PostScript multiple context extension. Context switching is implemented by a complex cooperation of C and PostScript code. + +Dictionaries have two special properties worth noting: + +They use an optimized storage representation if all the keys are names, which is almost always the case. + +They interact with a caching scheme used to accelerate name lookup in the interpreter. + +Names are allocated in blocks. The characters and hash chains are stored separately from the lookup cache information, so that in the future, most of the former can be compiled into the executable and shared or put in ROM. (This is not actually done yet.) + +Contexts: + psi/icontext.c, psi/icontext.h, psi/icstate.h. + +Dictionaries: + psi/iddict.h, psi/idict.h, psi/idict.c, psi/idictdef.h, psi/idicttpl.h. + +Names: + psi/iname.c, psi/iname.h, psi/inamedef.h, psi/inameidx.h, psi/inames.h, psi/inamestr.h. + + +Stacks +""""""""""""""""""""""" + +As mentioned above, each stack is allocated as a linked list of blocks. However, for reasonable performance, operators must normally be able to access their operands and produce their results using indexing rather than an access procedure. This is implemented by ensuring that all the operands of an operator are in the topmost block of the stack, using guard entries that cause an internal error if the condition isn't met. See psi/iostack.h for more details. + +Generic stacks: + psi/isdata.h, psi/istack.c, psi/istack.h, psi/istkparm.h. + +Specific stacks: + Dictionary stack: + psi/dstack.h, psi/iddstack.h, psi/idsdata.h, psi/idstack.c, psi/idstack.h. + + Execution stack: + psi/estack.h, psi/iesdata.h, psi/iestack.h. + + Operand stack: + psi/iosdata.h, psi/iostack.h, psi/ostack.h. + + +Interpreter loop +""""""""""""""""""""""" + + +Files: + psi/interp.c, psi/interp.h. + + +Scanning/parsing +""""""""""""""""""""""" +PostScript parsing consists essentially of token scanning, and is simple in principle. The scanner is complex because it must be able to suspend its operation at any time (i.e., between any two input characters) to allow an interpreter callout, if its input is coming from a procedure-based stream and the procedure must be called to provide more input data. + +Main scanner: + psi/iscan.c, psi/iscan.h, psi/iscannum.c, psi/iscannum.h, base/scanchar.h, base/scantab.c. + +Binary tokens: + psi/btoken.h, psi/ibnum.c, psi/ibnum.h, psi/inobtokn.c, psi/iscanbin.c, psi/iscanbin.h. + +DSC parsing: + psi/dscparse.c, psi/dscparse.h. + + +Standard operators +""""""""""""""""""""""" + +Non-output-related: + Filters: + psi/ifilter.h, psi/ifilter2.h, psi/ifrpred.h, psi/ifwpred.h, psi/istream.h, psi/zfbcp.c, psi/zfdctd.c, psi/zfdcte.c, psi/zfdecode.c, psi/zfilter.c, psi/zfilter2.c, psi/zfjbig2.c, psi/zfjpx.c, psi/zfmd5.c, psi/zfarc4.c, psi/zfproc.c, psi/zfrsd.c, psi/zfzlib.c. + + File and stream I/O: + psi/files.h, psi/itoken.h, psi/zbseq.c, psi/zdscpars.c, psi/zfile.h, psi/zfile.c, psi/zfile1.c, psi/zfileio.c, psi/ztoken.c. + + Data structures: + psi/zarray.c, psi/zdict.c, psi/zgeneric.c, psi/zpacked.c, psi/zstring.c. + + Functions: + psi/ifunc.h, psi/zfunc.c, psi/zfunc0.c, psi/zfunc3.c, psi/zfunc4.c, + + Other: + psi/ivmem2.h, psi/zalg.c, psi/zarith.c, psi/zcontext.c, psi/zcontrol.c, psi/zmath.c, psi/zmatrix.c, psi/zmisc.c, psi/zmisc1.c, psi/zmisc2.c, psi/zmisc3.c, psi/zrelbit.c, psi/zstack.c, psi/ztype.c, psi/zusparam.c, psi/zvmem.c, psi/zvmem2.c. + + + +Output-related: + Device management: + psi/zdevcal.c, psi/zdevice.c, psi/zdevice2.c, psi/ziodev.c, psi/ziodev2.c, psi/ziodevs.c, psi/zmedia2.c, + + Fonts and text: + psi/bfont.h, psi/ichar.h, psi/ichar1.h, psi/icharout.h, psi/icid.h, psi/ifcid.h, psi/ifont.h, psi/ifont1.h, psi/ifont2.h, psi/ifont42.h, psi/zbfont.c, psi/zcfont.c, psi/zchar.c, psi/zchar1.c, psi/zchar2.c, psi/zchar32.c, psi/zchar42.c, psi/zchar42.h, psi/zcharout.c, psi/zcharx.c, psi/zcid.c, psi/zfcid.c, psi/zfcid0.c, psi/zfcid1.c, psi/zfcmap.c, psi/zfont.c, psi/zfont0.c, psi/zfont1.c, psi/zfont2.c, psi/zfont32.c, psi/zfont42.c, psi/zfontenum.c. + + A bridge to the True Type bytecode interpreter: + base/gxttfb.c, base/gxttfb.h, base/ttfoutl.h, base/ttfmain.c, base/ttfmemd.c, base/ttfmemd.h, base/ttfinp.c, base/ttfinp.h. + + A reduced True Type bytecode interpreter: + (this is based in part on the work of the Freetype Team and incorporates some code from the FreeType 1 project) + base/ttfsfnt.h, base/ttcalc.c, base/ttcalc.h, base/ttcommon.h, base/ttconf.h, base/ttconfig.h, base/ttinterp.c, base/ttinterp.h, base/ttload.c, base/ttload.h, base/ttmisc.h, base/ttobjs.c, base/ttobjs.h, base/tttables.h, base/tttype.h, base/tttypes.h. + + Color, pattern, and halftone: + psi/icie.h, psi/icolor.h, psi/icremap.h, psi/icsmap.h, psi/iht.h, psi/ipcolor.h, psi/zcie.c, psi/zcolor.c, psi/zcolor1.c, psi/zcolor2.c, psi/zcolor3.c, psi/zcrd.c, psi/zcsindex.c, psi/zcspixel.c, psi/zcssepr.c, psi/zicc.c, psi/zht.c, psi/zht1.c, psi/zht2.h, psi/zht2.c, psi/zpcolor.c, psi/zshade.c, psi/ztrans.c. + + Images: + psi/iimage.h, psi/zimage.c, psi/zimage3.c, psi/zfimscale.c. + + Other graphics: + psi/igstate.h, psi/zdpnext.c, psi/zdps.c, psi/zdps1.c, psi/zgstate.c, psi/zpaint.c, psi/zpath.c, psi/zpath1.c, psi/ztrap.c, psi/zupath.c. + + +Operator support: + psi/oparc.h, psi/opcheck.h, psi/opdef.h, psi/oper.h, psi/opextern.h. + + +Non-standard operators +"""""""""""""""""""""""""""""""""""""""""""""" + +The interpreter includes many non-standard operators. Most of these provide some part of the function of a standard operator, so that the standard operator itself can be implemented in PostScript: these are not of interest to users, and their function is usually obvious from the way they are used. However, some non-standard operators provide access to additional, non-standard facilities that users might want to know about, such as transparency, RasterOp, and in-memory rendering. These are documented at :ref:`Additional Operators<Additional Operators>`. + +We don't document the complete set of non-standard operators here, because the set changes frequently. However, all non-standard operators are supposed to have names that begin with '.', so you can find them all by executing the following (Unix) command: + +``grep '{".[.]' psi/[zi]*.c`` + +In addition to individual non-standard operators implemented in the same files as standard ones, there are several independent optional packages of non-standard operators. As with other non-standard operators, the names of all the operators in these packages begin with '.'. We list those packages here. + +psi/zdouble.c + Provides "double" floating point arithmetic, using 8-byte strings to hold values. Developed under a contract; probably used only by the group that funded the development. + +psi/zfsample.c, + Provides a special operator to sample a given function and create a new type 0 function. + +psi/zsysvm.c + Provides operators for allocating objects in specific VM spaces, disregarding the current VM mode. + + +Interpreter support +"""""""""""""""""""""""""""""""""""""""""""""" + +Memory management (refs, GC, save/restore) -- see `Postscript Interpreter Extensions`_. + +Font API : + psi/ifapi.h, psi/zfapi.c, base/fapiufst.c, base/fapi_ft.c, base/wrfont.h, base/wrfont.c, base/write_t1.h, base/write_t1.c, base/write_t2.h, base/write_t2.c, + +Miscellaneous support: + psi/ierrors.h, base/gserrors.h, psi/ghost.h, psi/iconf.c, psi/iconf.h, psi/idparam.c, psi/idparam.h, psi/ilevel.h, psi/inouparm.c, psi/iparam.c, psi/iparam.h, psi/iparray.h, psi/iutil.c, psi/iutil.h, psi/iutil2.c, psi/iutil2.h, psi/iplugin.c, psi/iplugin.h. + + +PostScript code +"""""""""""""""""""""""""""""""""""""""""""""" + +Initialization and language support: + All configurations: + Resource/Init/gs_init.ps, Resource/Init/gs_statd.ps. + + Level 2: + Resource/Init/gs_btokn.ps, Resource/Init/gs_dps1.ps, Resource/Init/gs_dps2.ps, Resource/Init/gs_lev2.ps, Resource/Init/gs_res.ps, Resource/Init/gs_resmp.ps, Resource/Init/gs_setpd.ps. + + LanguageLevel 3: + Resource/Init/gs_frsd.ps, Resource/Init/gs_ll3.ps, Resource/Init/gs_trap.ps. + + Display PostScript: + Resource/Init/gs_dpnxt.ps, Resource/Init/gs_dps.ps. + + Emulation of other interpreters: + Resource/Init/gs_cet.ps (Adobe CPSI). + + +Color Spaces and support: + Color Space Loading: + Resource/Init/gs_cspace.ps, + + ICC color profiles: + Resource/Init/gs_icc.ps. + + +Font loading and support: + Font name mapping: + Resource/Init/Fontmap, lib/Fontmap.ATB, lib/Fontmap.ATM, Resource/Init/Fontmap.GS, lib/Fontmap.OS2, lib/Fontmap.OSF, lib/Fontmap.SGI, lib/Fontmap.Sol, lib/Fontmap.Ult, lib/Fontmap.VMS, lib/Fontmap.URW-136.T1, lib/Fontmap.URW-136.TT, Resource/Init/cidfmap, Resource/Init/FAPIcidfmap, Resource/Init/FAPIfontmap, Resource/Init/FCOfontmap-PCLPS2. + + Generic: + Resource/Init/gs_fonts.ps, Resource/Init/gs_fntem.ps. + + Type 1 and CFF: + Resource/Init/gs_cff.ps, Resource/Init/gs_diskf.ps, Resource/Init/gs_type1.ps. + + TrueType: + Resource/Init/gs_ttf.ps, Resource/Init/gs_typ42.ps. + + CID-keyed: + Resource/Init/gs_cidcm.ps, Resource/Init/gs_cidfn.ps, Resource/Init/gs_cmap.ps, Resource/Init/gs_ciddc.ps, Resource/Init/gs_cidfm.ps, Resource/Init/gs_cidtt.ps. + + Font API: + Resource/Init/gs_fapi.ps, Resource/Init/FAPIconfig, lib/FAPIconfig-FCO, Resource/Init/xlatmap. Resource/Init/FCOfontmap-PCLPS2. lib/FCOfontmap-PCLPS3. lib/FCOfontmap-PS3. + + Other: + lib/gs_kanji.ps, lib/gs_pfile.ps, Resource/Init/gs_typ32.ps. + + +Encodings: + Adobe-specified: + lib/gs_ce_e.ps, Resource/Init/gs_dbt_e.ps, Resource/Init/gs_il1_e.ps, Resource/Init/gs_mex_e.ps, Resource/Init/gs_mro_e.ps, Resource/Init/gs_pdf_e.ps, Resource/Init/gs_std_e.ps, Resource/Init/gs_sym_e.ps, Resource/Init/gs_wan_e.ps. + + Additional: + lib/gs_il2_e.ps, lib/gs_ksb_e.ps, lib/gs_wl1_e.ps, lib/gs_wl2_e.ps, lib/gs_wl5_e.ps. + + Pseudo-encodings for internal use: + lib/gs_lgo_e.ps, lib/gs_lgx_e.ps, Resource/Init/gs_mgl_e.ps. + + +Miscellaneous: + Image support: + Resource/Init/gs_img.ps, + + Emulation of %disk IODevice: + Resource/Init/gs_diskn.ps, + + Other support: + Resource/Init/gs_agl.ps, Resource/Init/gs_dscp.ps, Resource/Init/gs_epsf.ps, Resource/Init/gs_pdfwr.ps, lib/gs_rdlin.ps. + + X Windows icon bitmaps: + lib/gs_l.xbm, lib/gs_l.xpm, lib/gs_l_m.xbm, lib/gs_m.xbm, lib/gs_m.xpm, lib/gs_m_m.xbm, lib/gs_s.xbm, lib/gs_s.xpm, lib/gs_s_m.xbm, lib/gs_t.xbm, lib/gs_t.xpm, lib/gs_t_m.xbm. + + PDF/X-3 definition file sample: + lib/PDFX_def.ps + + +PDF interpreter +~~~~~~~~~~~~~~~~~~~~ + +Ghostscript's PDF interpreter is written entirely in PostScript, because its data structures are the same as PostScript's, and it is much more convenient to manipulate PostScript-like data structures in PostScript than in C. There is definitely a performance cost, but apparently not a substantial one: we considered moving the main interpreter loop (read a token using slightly different syntax than PostScript, push it on the stack if literal, look it up in a special dictionary for execution if not) into C, but we did some profiling and discovered that this wasn't accounting for enough of the time to be worthwhile. + +Until recently, there was essentially no C code specifically for the purpose of supporting PDF interpretation. The one major exception is the PDF 1.4 transparency features, which we (but not Adobe) have made available to PostScript code. + +In addition to patching the run operator to detect PDF files, the interpreter provides some procedures in Resource/Init/pdf_main.ps that are meant to be called from applications such as previewers. + +Files: + Resource/Init/pdf_base.ps, Resource/Init/pdf_draw.ps, Resource/Init/pdf_font.ps, Resource/Init/pdf_main.ps, Resource/Init/pdf_rbld.ps, Resource/Init/pdf_ops.ps, Resource/Init/pdf_sec.ps. + + +PostScript Printer Description +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A PostScript Printer Description tells a generic PostScript printer driver how to generate PostScript for a particular printer. Ghostscript includes a PPD file for generating PostScript intended to be converted to PDF. A Windows INF file for installing the PPD on Windows 2000 and XP is included. + +Files: + lib/ghostpdf.ppd, lib/ghostpdf.inf, lib/ghostpdf.cat, lib/ghostpdf.README. + +Build process +~~~~~~~~~~~~~~~~~~~~ + +Makefile structure +"""""""""""""""""""""""""" + +Ghostscript's makefiles embody a number of design decisions and assumptions that may not be obvious from a casual reading of the code. + +- All files are stored in subdirectories. The names of all subdirectories used in the build process are defined in the top-level makefiles for the various platforms: there are no "hard wired" directory names in any makefile rule. Subdirectory names in the makefiles are relative to the directory that is current at build time: normally this directory is the parent of the various subdirectories, and holds only a makefile, which in turn simply references the real top-level makefile in the source subdirectory. + +- All compiler and linker switches are likewise defined by macros, again preferably in the top-level platform makefile. + +- There is an absolute distinction between "source-like" subdirectories, which are read-only during the build process, and "object-like" subdirectories, all of whose contents are generated by the build process and which can be emptied (``rm *``) at any time with no bad effects. The source subdirectories are defined by macros named ``xxxSRCDIR``. + +- Object subdirectories may distinguish further between those that hold the results of the build process that are needed at run time (i.e., that should be included in a run-time distribution), defined by BINDIR, and those that are not needed at run time, defined by xxxGENDIR and xxxOBJDIR. (The distinction between these is historical and probably no longer relevant). + +- There may be multiple object subdirectories for different build configurations. On Unix, the obj and bin directories are used for normal production builds, the debugobj directory for debugging builds, and the pgobj directory for profiling builds; other platforms may use different conventions. The Unix makefiles support targets named debug and pg for debugging and profiling builds respectively; other platforms generally do not. + +- Makefiles will be maintained by hand. This requires editing the following makefile elements whenever the relevant source files changes: + + - Every header (.h) file must have a corresponding macro definition in a makefile. If abc.h #includes def.h and xyz.h, the definition must have the form: + ``xyz_h=$(xxxSRCD)xyz.h $(def_h) $(xyz_h)`` + + where ``xxxSRCD`` is the macro defining the relevant source directory (including a trailing '``/``'). Note that the '``.``' in the file name has been replaced by an underscore. Note also that the definition must follow all definitions it references, since some make programs expand macros in definitions at the time of definition rather than at the time of use. + + - Every .c file must have a corresponding rule in a makefile. If abc.c #includes def.h and lmn.h, the rule must have approximately the form: + + ``$(xxxOBJD)abc.$(OBJ) : $(xxxSRCD)abc.c $(def_h) $(lmn_h)`` + ``$(xxCC) $(xxO_)abc.$(OBJ) $(C_) $(xxxSRCD)abc.c`` + + where ``xxxSRCD`` is as before; ``xxxOBJD`` is the relevant object directory; ``xxCC`` defines the name of the C compiler plus the relevant compilation switches; and ``xxO_`` and ``C_`` are macros used to bridge syntactic differences between different make programs. + +The requirement to keep makefiles up to date by hand has been controversial. Two alternatives are generally proposed. + +- Programs like ``makedeps``, which generate build rules automatically from the #include lists in C files. We have found such programs useless: they "wire in" specific, concrete directory names, not only for our own code but even for the system header files; they have to be run manually whenever code files are added, renamed, or deleted, or whenever the list of #includes in any file changes; and they cannot deal with different source files requiring different compilation switches. + +- MSVC-style "project" files. These are equally useless: they are not portable across different vendors' tools -- in fact, there may not even be a usable import/export facility to convert their data to or from text form -- and they cannot combine configuration-independent data with configuration-specific data. + + +We have seriously considered writing our own build program in Tcl or Python that would eliminate these problems, or perhaps porting the tools developed by Digital's Vesta research project (if we can get access to them); however, either of these approaches would create potential portability problems of its own, not to mention difficulties in integrating with others' build systems. + +For more information about makefiles: + +- For a detailed list of makefiles, and a discussion of makefile issues related to portability, see the Makefiles_ section below. +- For more detailed information about editing configuration information in makefiles, see :ref:`Makefiles Overview<Make_MakeFilesOverview>`. +- For a complete example of adding a new driver to a makefile, see :ref:`Drivers<Drivers.htm>`. +- For a few more notes on makefile coding conventions, see :ref:`C-Style Makefiles<CStyle_Makefiles>`. + + + +.dev files +"""""""""""""""""""""""""" + +On top of the general conventions just described, Ghostscript's makefiles add a further layer of structure in order to support an open-ended set of fine-grained, flexible configuration options. Selecting an option (usually called a "module") for inclusion in the build may affect the build in many ways: + +- Almost always, it requires linking in some compiled code files. +- It may require running some additional initialization procedures at startup. +- It may require reading in some additional PostScript files at startup. For example, a Level 2 PostScript build requires support for PostScript resources and for ``setpagedevice``, which are implemented in PostScript code. +- It may require adding entries to a variety of internal tables that catalogue such things as drivers, IODevices, Function types, etc. +- It may require that other particular modules be included. For example, the "PostScript Level 2" module requires the modules for various filters, color spaces, etc. +- It may require removing some other (default) module from the build. For example, the core (Level 1) PostScript build has a "stub" for binary tokens, which are a Level 2 feature but are referenced by the core scanner: a Level 2 build must remove the stub. For more information about this, look for the string ``-replace`` in the makefiles and in ``base/genconf.c``. + + +Each module is defined in the makefiles by rules that create a file named ``xxx.dev``. The dependencies of the rule include all the files that make up the module (compiled code files, PostScript files, etc.); the body of the rule creates the .dev file by writing the description of the module into it. A program called genconf, described in the next section, merges all the relevant .dev files together. For examples of .dev rules, see any of the Ghostscript makefiles. + +Ultimately, a person must specify the root set of modules to include in a build (which of course may require other modules, recursively). Ghostscript's makefiles do this with a set of macros called ``FEATURE_DEVS`` and ``DEVICE_DEVSn``, defined in each top-level makefile, but nothing in the module machinery depends on this. + +Generators +"""""""""""""""""""""""""" + +Ghostscript's build procedure is somewhat unusual in that it compiles and then executes some support programs during the build process. These programs then generate data or source code that is used later on in the build. + +The most important and complex of the generator programs is genconf. genconf merges all the .dev files that make up the build, and creates three or more output files used in later stages: + +- ``gconfig.h``, consisting mainly of macro calls, one call per "resource" making up the build, other than "resources" listed in the other output files. +- ``gconfigf.h``, produced only for PostScript builds with compiled-in fonts, consisting of one macro call per font. +- A linker control file whose name varies from one platform to another, containing the list of compiled code files to be linked. +- If necessary, another linker control file, also varying between platforms, that contains other information for the linker such as the list of system libraries to be searched. (On Unix platforms, the two linker control functions are combined in a single file). + + +Source generators: + base/genarch.c + Creates a header file containing a variety of information about the hardware and compiler that isn't provided in any standard system header file. Always used. + + base/genconf.c (also generates non-source) + Constructs header files and linker control files from the collection of options and modules that make up the build. See above. Always used. + + base/genht.c + Converts a PostScript halftone (in a particular constrained format) to a C data structure that can be compiled into an executable. Only used if any such halftones are included in the build. + + base/mkromfs.c + Takes a set of directories, and creates a compressed filesystem image that can be compiled into the executable as static data and accessed through the %rom% iodevice prefix. This is used to implement the ``COMPILE_INITS=1`` feature (a compressed init fileset is more efficient than the current 'gsinit.c' produced by 'geninit.c'). This IODevice is more versatile since other files can be encapsulated such as fonts, helper PostScript files and Resources. The list of files is defined in part in psi/psromfs.mak. + + +Other generators: + base/echogs.c + Implements a variety of shell-like functions to get around quirks, limitations, and omissions in the shells on various platforms. Always used. + + base/genconf.c (also generates source) + See above. + + base/gendev.c (not used) + Was intended as a replacement for genconf, but was never completed. + + +Support +"""""""""""""""""""""""""" + +There are a number of programs, scripts, and configuration files that exist only for the sake of the build process. + +Files for PC environments: + base/gswin.icx, base/gswin16.icx, base/bcc32.cfg, base/cp.bat, base/cp.cmd, psi/dw32c.def, psi/dwmain.rc, psi/dwmain32.def, psi/dwsetup.def, psi/dwsetup_x86.manifest, psi/dwsetup_x64.manifest, psi/dwuninst.def, psi/dwuninst_x86.manifest, psi/dwuninst_x64.manifest, psi/gsdll2.def, psi/gsdll2.rc, psi/gsdll32.def, psi/gsdll32.rc, psi/gsdll32w.lnk, psi/gsos2.def, psi/gsos2.icx, psi/gsos2.rc, base/gspmdrv.def, base/gspmdrv.icx, base/gspmdrv.rc, base/gswin.rc, base/gswin32.rc, base/mv.bat, base/mv.cmd, base/rm.bat, base/rm.cmd, + +Files for MacOS: + lib/Info-macos.plist. + +Files for OpenVMS: + base/append_l.com, base/copy_one.com, base/rm_all.com, base/rm_one.com. + +Other files: + base/bench.c, base/catmake, base/instcopy. + + +Utilities +~~~~~~~~~~~~~ + +Ghostscript comes with many utilities for doing things like viewing bitmap files and converting between file formats. Some of these are written in PostScript, some as scripts, and some as scripts that invoke special PostScript code. + +Utilities in PostScript +"""""""""""""""""""""""""""""" + +These are all documented in doc/Psfiles.htm, q.v. + +Utility scripts +"""""""""""""""""""""""""""""" + +Many of these scripts come in both Unix and MS-DOS (.bat versions; some also have an OS/2 (.cmd) version. The choice of which versions are provided is historical and irregular. These scripts should all be documented somewhere, but currently, many of them have man pages, a few have their own documentation in the doc directory, and some aren't documented at all. + +Script files without PC versions: + lib/afmdiff.awk, lib/dvipdf, lib/lprsetup.sh, lib/pphs, lib/printafm, lib/unix-lpr.sh, lib/wftopfa. + +Script files with PC versions: + lib/eps2eps, lib/eps2eps.bat, lib/eps2eps.cmd, lib/ps2ps2, lib/ps2ps2.bat, lib/ps2ps2.cmd, lib/font2c, lib/font2c.bat, lib/font2c.cmd, lib/gsbj, lib/gsbj.bat, lib/gsdj, lib/gsdj.bat, lib/gsdj500, lib/gsdj500.bat, lib/gslj, lib/gslj.bat, lib/gslp, lib/gslp.bat, lib/gsnd, lib/gsnd.bat, lib/pdf2dsc, lib/pdf2dsc.bat, lib/pdf2ps, lib/pdf2ps.bat, lib/pdf2ps.cmd, lib/pf2afm, lib/pf2afm.bat, lib/pf2afm.cmd, lib/pfbtopfa, lib/pfbtopfa.bat, lib/ps2ascii, lib/ps2ascii.bat, lib/ps2ascii.cmd, lib/ps2epsi, lib/ps2epsi.bat, lib/ps2epsi.cmd, lib/ps2pdf, lib/ps2pdf.bat, lib/ps2pdf.cmd, lib/ps2pdf12, lib/ps2pdf12.bat, lib/ps2pdf12.cmd, lib/ps2pdf13, lib/ps2pdf13.bat, lib/ps2pdf13.cmd, lib/ps2pdf14, lib/ps2pdf14.bat, lib/ps2pdf14.cmd, lib/ps2pdfwr, lib/ps2pdfxx.bat, lib/ps2ps, lib/ps2ps.bat, lib/ps2ps.cmd. + +Script files with only PC versions: + lib/gsndt.bat, lib/gssetgs.bat, lib/gssetgs32.bat, lib/gssetgs64.bat, lib/gst.bat, lib/gstt.bat, lib/lp386.bat, lib/lp386r2.bat, lib/lpgs.bat, lib/lpr2.bat, lib/pftogsf.bat, lib/wmakebat.bat. + + + +Memory management +--------------------- + +Memory manager architecture +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In many environments, the memory manager is a set of library facilities that implicitly manage the entire address space in a homogenous manner. Ghostscript's memory manager architecture has none of these properties: + +- Rather than a single library accessed as procedures, Ghostscript includes multiple allocator types, each of which in turn may have multiple instances (allocators). Allocators are 'objects' with a substantial set of virtual functions. +- Rather than managing the entire address space, each allocator manages a storage pool, which it may or may not be able to expand or reduce by calling on a 'parent' allocator. +- Rather than a single genus of untyped storage blocks, Ghostscript's allocators provide two genera -- type-tagged 'objects', and 'strings' -- with substantially different properties. + +Objects vs strings +"""""""""""""""""""""" + +As noted above, allocators provide two different storage genera. + +Objects: + +- Are aligned in storage to satisfy the most stringent alignment requirement imposed by the CPU or compiler; +- Can be referenced only by pointers to their start, not to any internal location, unless special arrangements are made; +- May contain pointers to other objects, or to strings; +- Have an associated structure descriptor that specifies their size (usually) and the location of any pointers contained within them. + + +Given a pointer to an object, the allocator that allocated it must be able to return the object's size and the pointer to its structure descriptor. (It is up to the client to know what allocator allocated an object.) + +Strings: + +- Are not aligned in storage; +- Can be referenced by pointers (consisting of a starting address and a length) to any substring, starting anywhere within the string; +- May not contain pointers; +- Do not have a structure descriptor. + +The object/string distinction reflects a space/capability tradeoff. The per-object space overhead of the standard type of allocator is typically 12 bytes; this is too much to impose on every string of a few bytes. On the other hand, restricting object pointers to reference the start of the object currently makes object garbage collection and compaction more space-efficient. If we were to redesign the standard allocator, we would probably opt for a different design in which strings were allocated within container objects of a few hundred bytes, and pointers into the middle of all objects were allowed. + + +.. _Develop_Structure_Descriptors: + +Structure descriptors +"""""""""""""""""""""""""""""""""""""""""""" + +Every object allocated by a Ghostscript allocator has an associated structure descriptor, which the caller provides when allocating the object. The structure descriptor serves several purposes: + +- Specifying the size of the object for allocation; +- Providing pointer-enumeration and pointer-relocation procedures for the garbage collector; +- Providing an optional finalization procedure to be called when the object is freed (either explicitly or automatically). + +Structure descriptors are read-only, and are normally defined statically using one of the large set of ``gs_private_st_`` or ``gs_public_st_`` macros in base/gsstruct.h. + +While the structure descriptor normally specifies the size of the object, one can also allocate an array of bytes or objects, whose size is a multiple of the size in the descriptor. For this reason, every object stores its size as well as a reference to its descriptor. + +Because the standard Ghostscript garbage collector is non-conservative and can move objects, every object allocated by a Ghostscript allocator must have an accurate structure descriptor. If you define a new type of object (structure) that will be allocated in storage managed by Ghostscript, you must create an accurate descriptor for it, and use that descriptor to allocate it. The process of creating accurate descriptors for all structures was long and painful, and accounted for many hard-to-diagnose bugs. + +By convention, the structure descriptor for structure type ``xxx_t`` is named ``st_xxx`` (this is preferred), or occasionally ``st_xxx_t``. + +Note that a structure descriptor is only required for objects allocated by the Ghostscript allocator. A structure type ``xxx_t`` does not require a structure descriptor if instances of that type are used only in the following ways: + +- Instances are allocated only on the C stack, e.g., as ``xxx_t``, ``xxx1``, ``xxx2``;, or on the C heap, with malloc or through the Ghostscript "wrapper" defined in base/gsmalloc.h. + +- Pointers to instances are not stored in places where the garbage collector will try to trace the pointer. +- Code never attempts to get the structure type or size of an instance through the allocator API. + +In general, structures without descriptors are problem-prone, and are deprecated; in new code, they should only be used if the structure is confined to a single .c file and its instances are only allocated on the C stack. + +Files: + base/gsstruct.h, base/gsstype.h. + +Garbage collection +"""""""""""""""""""""" + +The allocator architecture is designed to support compacting garbage collection. Every object must be able to enumerate all the pointers it contains, both for tracing and for relocation. As noted just above, the structure descriptor provides procedures that do this. + +Whether or not a particular allocator type actually provides a garbage collector is up to the allocator: garbage collection is invoked through a virtual procedure. In practice, however, there are only two useful garbage collectors for Ghostscript's own allocator: + +- The "real" garbage collector associated with the PostScript interpreter, described :ref:`below<Interpreter_GC>`; +- A "non" garbage collector that only merges adjacent free blocks. + +As noted above, because the architecture supports compacting garbage collection, a "real" garbage collector cannot be run at arbitrary times, because it cannot reliably find and relocate pointers that are on the C stack. In general, it is only safe to run a "real" garbage collector when control is at the top level of the program, when there are no pointers to garbage collectable objects from the stack (other than designated roots). + +Files: + base/gsgc.h, base/gsnogc.c, base/gsnogc.h. + + +Movability +"""""""""""""""""""""" +As just noted, objects are normally movable by the garbage collector. However, some objects must be immovable, usually because some other piece of software must retain pointers to them. The allocator API includes procedures for allocating both movable (default) and immovable objects. Note, however, that even immovable objects must be traceable (have a structure descriptor), and may be freed, by the garbage collector. + + + +Parent hierarchy +"""""""""""""""""""""" + +When an allocator needs to add memory to the pool that it manages, it requests the memory from its parent allocator. Every allocator has a pointer to its parent; multiple allocators may share a single parent. The ultimate ancestor of all allocators that can expand their pool dynamically is an allocator that calls malloc, described below. However, especially in embedded environments, an allocator may be limited to a fixed-size pool assigned to it when it is created. + +Allocator API +"""""""""""""""""""""" + +In summary, the allocator API provides the following principal operations: + +- Allocate and free movable (default) or immovable objects and strings. +- Return the structure type and size of an object. +- Resize (shrink or grow) movable objects and strings, preserving the contents insofar as possible. +- Report the size of the managed pool, and how much of it is in use. +- Register and unregister root pointers for the garbage collector. +- Free the allocator itself. +- Consolidate adjacent free blocks to reduce fragmentation. + +For details, see base/gsmemory.h. + +The allocator API also includes one special hook for the PostScript interpreter: the concept of stable allocators. See the section on "save and restore" below for details. + +Files: + base/gsmemraw.h, base/gsmemory.c, base/gsmemory.h, base/gsstruct.h, base/gsstype.h. + +Freeing storage +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript's memory management architecture provides three different ways to free objects: explicitly, by reference counting, or by garbage collection. They provide different safety / performance / convenience tradeoffs; we believe that all three are necessary. + +Objects are always freed as a whole; strings may be freed piecemeal. + +An object may have an associated finalization procedure, defined in the structure descriptor. This procedure is called just before the object is freed, independent of which method is being used to free the object. A few types of objects have a virtual finalization procedure as well: the finalization procedure defined in the descriptor simply calls the one in the object. + +Explicit freeing +"""""""""""""""""""""" + +Objects and strings may be freed explicitly, using the ``gs_free_`` virtual procedures in the allocator API. It is up to the client to ensure that all allocated objects are freed at most once, and that there are no dangling pointers. + +Explicit freeing is the fastest method, but is the least convenient and least safe. It is most appropriate when storage is freed in the same procedure where it is allocated, or for storage that is known to be referenced by only one pointer. + +Reference counting +"""""""""""""""""""""" + +Objects may be managed by reference counting. When an object is allocated, its reference count may be set to 0 or 1. Subsequently, when the reference count is decremented to 0, the object is freed. + +The reference counting machinery provides its own virtual finalization procedure for all reference-counted objects. The machinery calls this procedure when it is about to free the object (but not when the object is freed in any other way, which is probably a design bug). This is in addition to (and called before) any finalization procedure associated with the object type. + +Reference counting is as fast as explicit freeing, but takes more space in the object. It is most appropriate for relatively large objects which are referenced only from a small set of pointers. Note that reference counting cannot free objects that are involved in a pointer cycle (e.g., A -> B -> C -> A). + +Files: + base/gsrefct.h. + + +(Real) garbage collection +"""""""""""""""""""""""""""""""""""""""""""" + +Objects and strings may be freed automatically by a garbage collector. See :ref:`below<Interpreter_GC>`. + +Special implementations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +malloc +"""""""""""""""""""""""""""""""""""""""""""" + +As mentioned :ref:`above<Parent hierarchy>`, the ultimate ancestor of all allocators with an expandable pool is one that calls malloc. + +Note that the default gsmalloc.c allocator for malloc/free now uses a mutex so that allocators that use this can be assured of thread safe behavior. + +Files: + base/gsmalloc.h, base/gsmalloc.c. + +Locking +"""""""""""""""""""""""""""""""""""""""""""" + +In a multi-threaded environment, if an allocator must be callable from multiple threads (for example, if it is used to allocate structures in one thread that are passed to, and freed by, another thread), the allocator must provide mutex protection. Ghostscript provides this capability in the form of a wrapper allocator, that simply forwards all calls to a target allocator under protection of a mutex. Using the wrapper technique, any allocator can be made thread-safe. + +Files: + base/gsmemlok.h, base/gsmemlok.c. + +Retrying +"""""""""""""""""""""""""""""""""""""""""""" + +In an embedded environment, job failure due to memory exhaustion is very undesirable. Ghostscript provides a wrapper allocator that, when an allocation attempt fails, calls a client-provided procedure that can attempt to free memory, then ask for the original allocation to be retried. For example, such a procedure can wait for a queue to empty, or can free memory occupied by caches. + +Files: + base/gsmemret.h, base/gsmemret.c. + +Chunk +"""""""""""""""""""""""""""""""""""""""""""" + +When multiple threads are used and there may be frequent memory allocator requests, mutex contention is a problem and can cause severe performance degradation. The chunk memory wrapper can provide each thread with its own instance of an allocator that only makes requests on the underlying (non-GC) alloctor when large blocks are needed. Small object allocations are managed within chunks. + +This allocator is intended to be used on top of the basic 'gsmalloc' allocator (malloc/free) which is NOT garbage collected or relocated and which MUST be mutex protected. + +Files: + base/gsmchunk.h, base/gsmchunk.c. + +Standard implementation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The standard Ghostscript allocator gets storage from its parent (normally the malloc allocator) in large blocks called clumps, and then allocates objects up from the low end and strings down from the high end. Large objects or strings are allocated in their own clump. + +The standard allocator maintains a set of free-block lists for small object sizes, one list per size (rounded up to the word size), plus a free-block list for large objects (but not for objects so large that they get their own clump: when such an object is freed, its chunk is returned to the parent). The lists are not sorted; adjacent blocks are only merged if needed. + +While the standard allocator implements the generic allocator API, and is usable with the library alone, it includes a special hook for the PostScript interpreter to aid in the efficient allocation of PostScript composite objects (arrays and dictionaries). See the section on Refs below for details. + +Files: + base/gsalloc.c, base/gsalloc.h, base/gxalloc.h, base/gxobj.h. + + +PostScript interpreter extensions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PostScript interpreter uses an allocator that extends the graphic library's standard allocator to handle PostScript objects, save and restore, and real garbage collection. + +Refs (PostScript "objects") +"""""""""""""""""""""""""""""""""""""""""""" + +Ghostscript represents what the PLRM calls PostScript "objects" using a structure called a ref, defined in psi/iref.h; packed refs, used for the elements of packed arrays, are defined in psi/ipacked.h. See those files for detailed information. + +Files: + psi/ipacked.h, psi/iref.h. + +The PLRM calls for two types of "virtual memory" (VM) space: global and local. Ghostscript adds a third space, system VM, whose lifetime is an entire session -- i.e., it is effectively "permanent". All three spaces are subject to garbage collection. There is a separate allocator instance for each VM space (actually, two instances each for global and local spaces; see below). In a system with multiple contexts and multiple global or local VMs, each global or local VM has its own allocator instance(s). + +Refs that represent PostScript composite objects, and therefore include pointers to stored data, include a 2-bit VM space tag to indicate in which VM the object data are stored. In addition to system, global, and local VM, there is a tag for "foreign" VM, which means that the memory is not managed by a Ghostscript allocator at all. Every store into a composite object must check for invalidaccess: the VM space tag values are chosen to help make this check efficient. See psi/ivmspace.h, psi/iref.h, and psi/store.h for details. + +Files: + psi/ivmspace.h. + +PostScript composite objects (arrays and dictionaries) are usually small. Using a separate memory manager object for each composite object would waste a lot of space for object headers. Therefore, the interpreter's memory manager packs multiple composite objects (also called "ref-containing objects") into a single memory manager object, similar to the way the memory manager packs multiple objects into a clump (see above). See base/gxalloc.h for details. This memory manager object has a structure descriptor, like all other memory manager objects. + +Note that the value.pdict, value.refs, or value.packed member of a ref must point to a PostScript composite object, and therefore can point into the middle of a memory manager object. This requires special handling by the garbage collector (q.v.). + +Files: + psi/ialloc.c, psi/ialloc.h, psi/iastate.h, psi/iastruct.h, psi/ilocate.c, psi/imemory.h, psi/istruct.h. + save/.forgetsave/restore + +In addition to save and restore, Ghostscript provides a .forgetsave operator that makes things as though a given save had never happened. (In data base terminology, save is "begin transaction", restore is "abort transaction", and .forgetsave is "end/commit transaction"). .forgetsave was implemented for a specific commercial customer (who may no longer even be using it): it was a pain to make work, but it's in the code now, and should be maintained. See the extensive comments in psi/isave.c for more information about how these operations work. + +Files: + psi/idosave.h, psi/isave.c, psi/isave.h, psi/isstate.h, psi/store.h. + + +Stable allocators +"""""""""""""""""""" + +Even though ``save`` and ``restore`` are concepts from the PostScript interpreter, the generic allocator architecture and API include a feature to support them, called stable allocators. Every allocator has an associated stable allocator, which tags pointers with the same VM space number but which is not subject to save and restore. System VM is intrinsically stable (its associated stable allocator is the same allocator), so there are only 5 allocators in ordinary single-context usage: system VM, stable global VM, ordinary global VM, stable local VM, ordinary local VM. + +The reason that we cannot simply allocate all stable objects in system VM is that their refs must still be tagged with the correct VM space number, so that the check against storing pointers from global VM to local VM can be enforced properly. + +All PostScript objects are normally allocated with the non-stable allocators. The stable allocators should be used with care, since using them can easily create dangling pointers: if storage allocated with a stable allocator contains any references to PostScript objects, the client is responsible for ensuring that the references don't outlive the referenced objects, normally by ensuring that any such referenced objects are allocated at the outermost save level. + +The original reason for wanting stable allocators was the PostScript stacks, which are essentially PostScript arrays but are not subject to save and restore. Some other uses of stable allocators are: + +- Several per-context structures for DPS. +- Paths (see ``gstate_path_memory`` in base/gsstate.c. +- Row buffers for images (see ``gs_image_row_memory`` in base/gsimage.c), because the data-reading procedure for an image can invoke save and restore. +- Notification lists for fonts, to handle the sequence allocate .. save .. register .. restore. +- The parameter lists for pdfwrite and epswrite devices (in devices/vector/gdevpsdp.c), because the whole issue of local vs. global VM for ``setpagedevice`` is, in the words of Ed Taft of Adobe, "a mess". +- Many places in the pdfwrite driver, because many of its bookkeeping structures must not be restorable. + + +For more specific examples, search the sources for references to ``gs_memory_stable``. + + +.. _Interpreter_GC: + +Garbage collection +""""""""""""""""""""""" + +The interpreter's garbage collector is a compacting, non-conservative, mark-and-sweep collector. + +- It compacts storage because that is the only way to avoid permanent sandbars, which is essential in limited-memory environments. +- It is non-conservative because conservative collectors (which attempt to determine whether arbitrary bit patterns are pointers) cannot compact. +- It uses mark-and-sweep, rather than a more modern copying approach, because it cannot afford the extra memory required for copying. + + +Because the garbage collector is non-conservative, it cannot be run if there are any pointers to movable storage from the C stack. Thus it cannot be run automatically when the allocator is unable to allocate requested space. Instead, when the allocator has allocated a given amount of storage (the ``vm_threshold`` amount, corresponding to the PostScript ``VMThreshold`` parameter), it sets a flag that the interpreter checks in the main loop. When the interpreter sees that this flag is set, it calls the garbage collector: at that point, there are no problematic pointers from the stack. + +Roots for tracing must be registered with the allocator. Most roots are registered during initialization. + +"Mark-and-sweep" is a bit of a misnomer. The garbage collector actually has 5 main phases: + +- Sweep to clear marks; +- Trace and mark; +- Sweep to compute relocation; +- Sweep to relocate pointers; +- Sweep and compact. + + +There is some extra complexity to handle collecting local VM only. In this case, all pointers in global VM are treated as roots, and global VM is not compacted. + +As noted above, PostScript arrays and strings can have refs that point within them (because of ``getinterval``). Thus the garbage collector must mark each element of an array, and even each byte of a string, individually. Specifically, it marks objects, refs, and strings using 3 different mechanisms: + +- Objects have a mark bit in their header: see base/gxobj.h, +- Refs and packed refs have a reserved mark bit: see psi/iref.h and psi/ipacked.h. +- Strings use a separate bit table, with one bit per string byte: see base/gxalloc.h, + +Similarly, it records the relocation information for objects, refs, and strings differently: + +- Objects record relocation in the object header. +- Refs record relocation in unused fields of refs such as nulls that don't use their value field. Every memory manager object that stores ref-containing objects as described above has an extra, unused ref at the end for this purpose. +- Strings use a separate relocation table. + +Files: + psi/igc.c, psi/igc.h, psi/igcref.c, psi/igcstr.c, psi/igcstr.h, psi/ireclaim.c. + + +Portability +~~~~~~~~~~~~~~~~~~~~~~~ + +One of Ghostscript's most important features is its great portability across platforms (CPUs, operating systems, compilers, and build tools). The code supports portability through two mechanisms: + +- `Structural mechanisms`_ -- segregating platform-dependent information into files in a particular way. +- `Coding standards`_ -- avoiding relying on byte order, scalar size, and platform-specific compiler or library features. + + + + +Structural mechanisms +""""""""""""""""""""""""" + +CPU and compiler +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Ghostscript attempts to discover characteristics of the CPU and compiler automatically during the build process, by compiling and then executing a program called genarch. genarch generates a file ``obj/arch.h``, which almost all Ghostscript files then include. This works well for things like word size, byte order, and floating point representation, but it can't determine whether or not a compiler supports a particular feature, because if a feature is absent, the compilation may fail. + +Files: + base/genarch.c, obj/arch.h. + +Library headers +^^^^^^^^^^^^^^^^^^^^^^^^^^ +Despite the supposed standardization of ANSI C, platforms vary considerably in where (and whether) they provide various standard library facilities. Currently, Ghostscript's build process doesn't attempt to sort this out automatically. Instead, for each library header file ``<xxx.h>`` there is a corresponding Ghostscript source file ``base/xxx_.h``, containing a set of compile-time conditionals that attempt to select the correct platform header file, or in some cases substitute Ghostscript's own code for a missing facility. You may need to edit these files when moving to platforms with unusually non-standard libraries. + +Files: + ``base/ctype_.h``, ``base/dirent_.h``, ``base/dos_.h``, ``base/errno_.h``, ``base/fcntl_.h``, ``base/jerror_.h``, ``base/malloc_.h``, ``base/math_.h``, ``base/memory_.h``, ``base/pipe_.h``, ``base/png_.h``, ``base/setjmp_.h``, ``base/stat_.h``, ``base/stdint_.h``, ``base/stdio_.h``, ``base/string_.h``, ``base/time_.h``, ``base/unistd_.h``, ``base/vmsmath.h``, ``base/windows_.h``, ``base/x_.h`` + +It has been suggested that the GNU configure scripts do the above better, for Unix systems, than Ghostscript's current methods. While this may be true, we have found configure scripts difficult to write, understand, and maintain; and the autoconf tool for generating configure scripts, which we found easy to use, doesn't cover much of the ground that Ghostscript requires. + +Cross-platform APIs +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For a few library facilities that are available on all platforms but are not well standardized, or that may need to be changed for special environments, Ghostscript defines its own APIs. It is an architectural property of Ghostscript that the implementations of these APIs are the only .c files for which the choice of platform (as opposed to choices of drivers or optional features) determines whether they are compiled and linked into an executable. + +API: + base/gp.h, base/gpcheck.h, base/gpgetenv.h, base/gpmisc.h, base/gpsync.h. + + +Implementation files shared among multiple platforms: + base/gp_getnv.c, base/gp_mktmp.c, base/gp_nsync.c, base/gp_paper.c, base/gp_psync.c, base/gp_strdl.c, base/gpmisc.c. + + +Platform-specific implementation files: + base/gp_dosfe.c, base/gp_dosfs.c, base/gp_dvx.c, base/gp_msdos.c, base/gp_mshdl.c, base/gp_mslib.c, base/gp_mswin.c, base/gp_mswin.h, base/gp_ntfs.c, base/gp_os2.c, base/gp_os2.h, base/gp_os2fs.c, base/gp_os9.c, base/gp_stdia.c, base/gp_stdin.c, base/gp_unifn.c, base/gp_unifs.c, base/gp_unix.c, base/gp_unix_cache.c, base/gp_upapr.c, base/gp_vms.c, base/gp_wgetv.c, base/gp_win32.c, base/gp_wpapr.c, base/gp_wsync.c, base/gs_dll_call.h. + + +Makefiles +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For information on the structure and conventions used within makefiles, see the `Makefile structure`_ section above. + +Ghostscript's makefiles are structured very similarly to the cross-platform library files. The great majority of the makefiles are portable across all platforms and all versions of make. To achieve this, the platform-independent makefiles must obey two constraints beyond those of the POSIX make program: + +- No conditionals or includes are allowed. While most make programs now provide some form of conditional execution and some form of inclusion, there is no agreement on the syntax. (Conditionals and includes are allowed in platform-dependent makefiles; in fact, an inclusion facility is required.) +- There must be a space on both sides of the : that separates the target of a rule from its dependencies. This is required for compatibility with the OpenVMS MMS and MMK programs. + + +The top-level makefile for each platform (where "platform" includes the OS, the compiler, and the flavor of make) contains all the build options, plus includes for the generic makefiles and any platform-dependent makefiles that are shared among multiple platforms. + +While most of the top-level makefiles build a PostScript and/or PDF interpreter configuration, there are also a few makefiles that build a test program that only uses the graphics library without any language interpreter. Among other things, this can be helpful in verifying that no accidental dependencies on the interpreter have crept into the library or drivers. + +For families of similar platforms, the question arises whether to use multiple top-level makefiles, or whether to use a single top-level makefile that may require minor editing for some (or all) platforms. Ghostscript currently uses the following top-level makefiles for building interpreter configurations: + + +- POSIX systems (inluding Linux and Unix): + - GNU Autoconf source script for automatic build configuration. + - Makefile.in, source for the top-level makefile used in the Autoconf build. + - base/unix-gcc.mak, for Unix with gcc. + - base/unixansi.mak, for Unix with an ANSI C compiler other than gcc. +- PC: + - ghostscript.vcproj, Visual Studio project file used to build Ghostscript. + - psi/msvc32.mak, for MS Windows with Microsoft Visual C (MSVC). + - psi/os2.mak, for MS-DOS or OS/2 GCC/EMX environment. +- Macintosh: + - base/macosx.mak, commandline makefile for MacOS X. + - base/macos-mcp.mak, dummy makefile to generate an xml project file for Metrowerks Codewarrior. +- Other: + - base/all-arch.mak, for building on many Unix systems in a networked test environment. + - base/openvms.mak, for OpenVMS with Digital's CC compiler and the MMS build program. + - base/openvms.mmk, for OpenVMS with Digital's CC compiler and the MMK build program. + +The following top-level makefiles build the library test program: + +- base/ugcclib.mak, on Unix with gcc. +- base/msvclib.mak, on MS Windows with MSVC. + +The MSVC makefiles may require editing to select between different versions of MSVC, since different versions may have slightly incompatible command line switches or customary installation path names. The Unix makefiles often require editing to deal with differing library path names and/or library names. For details, see the :ref:`Unix section of the documentation<MakeHowToBuildForUnix>` for building Ghostscript. + +Library test program: + base/gslib.c. + +Platform-independent makefiles: + Graphics library and support: + devices/contrib.mak, devices/devs.mak, base/gs.mak, base/lib.mak, base/version.mak. + + PostScript interpreter and fonts: + psi/int.mak. + + Third-party libraries: + base/expat.mak, base/ijs.mak, base/jbig2.mak, base/ldf_jb2.mak, base/lwf_jp2.mak, base/jpeg.mak, base/png.mak, base/zlib.mak. + + +Shared platform-dependent makefiles: + Unix: + base/unix-aux.mak, base/unix-dll.mak, base/unix-end.mak, base/unixhead.mak, base/unixinst.mak, base/unixlink.mak. + + Microsoft Windows and MS-DOS: + base/msvccmd.mak, base/msvctail.mak, base/pcwin.mak, psi/winint.mak, base/winlib.mak, base/winplat.mak. + + +Coding standards +""""""""""""""""""" + +Coding for portability requires avoiding both explicit dependencies, such as platform-dependent ``#ifdefs``, and implicit dependencies, such as dependencies on byte order or the size of the integral types. + +Explicit dependencies +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The platform-independent .c files never, ever, use ``#ifdef`` or ``#if`` to select code for specific platforms. Instead, we always try to characterize some abstract property that is being tested. For example, rather than checking for macros that are defined on those specific platforms that have 64-bit long values, we define a macro ARCH_SIZEOF_LONG that can then be tested. Such macros are always defined in a .h file, either automatically in arch.h, or explicitly in a ``xxx_.h`` file, as described in earlier sections. + +Files: + base/std.h, base/stdpn.h, base/stdpre.h. + +Implicit dependencies +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The most common source of byte ordering dependencies is casting between types (``T1 *``) and (``T2 *``) where ``T1`` and ``T2`` are numeric types that aren't merely signed/unsigned variants of each other. To avoid this, the only casts allowed in the code are between numeric types, from a pointer type to a long integral type, and between pointer types. + +Ghostscript's code assumes the following about the sizes of various types: + +char + 8 bits + +short + 16 bits + +int + 32 or 64 bits + +long + 32 or 64 bits + +float + 32 bits (may work with 64 bits) + +double + 64 bits (may work with 128 bits) + +The code does not assume that the char type is signed (or unsigned); except for places where the value is always a literal string, or for interfacing to library procedures, the code uses ``byte`` (a Ghostscript synonym for ``unsigned char``) almost everywhere. + +Pointers are signed on some platforms and unsigned on others. In the few places in the memory manager where it's necessary to reliably order-compare (as opposed to equality-compare) pointers that aren't known to point to the same allocated block of memory, the code uses the PTR_relation macros rather than direct comparisons. + +See the files listed above for other situations where a macro provides platform-independence or a workaround for bugs in specific compilers or libraries (of which there are a distressing number). + +Platform-specific code +"""""""""""""""""""""""""""""""" + +There are some features that are inherently platform-specific: + +- Microsoft Windows requires a lot of special top-level code, and also has an installer and uninstaller. +- OS/2 requires a little special code. +- MacOS also requires special top-level code (now distributed with the standard Ghostscript package). +- All platforms supporting DLLs (currently all three of the above) share some special top-level code. + + +MS Windows files: + psi/dpmain.c, psi/dwdll.c, psi/dwdll.h, psi/dwimg.c, psi/dwimg.h, psi/dwmain.c, psi/dwmainc.c, psi/dwnodll.c, psi/dwreg.c, psi/dwreg.h, psi/dwres.h, psi/dwtext.c, psi/dwtext.h, psi/dwtrace.c, psi/dwtrace.h, base/gp_msdll.c, base/gp_mspol.c, base/gp_msprn.c, base/gsdllwin.h. + +OS/2 files: + base/gp_os2pr.c, + +Unix files: + psi/dxmain.c, psi/dxmainc.c. + +Macintosh files: + devices/gdevmac.c, devices/gdevmac.h, devices/gdevmacpictop.h, devices/gdevmacttf.h, base/gp_mac.c, base/gp_mac.h, base/gp_macio.c, base/gp_macpoll.c, base/gsiomacres.c, base/macgenmcpxml.sh, base/macsystypes.h, base/macos_carbon_pre.h, base/macos_carbon_d_pre.h, base/macos_classic_d_pre.h, psi/dmmain.c, psi/dmmain.r. + +VMS files: + base/vms_x_fix.h. + +DLL files: + psi/gsdll.c, base/gsdll.h, devices/gdevdsp.c, devices/gdevdsp.h, devices/gdevdsp2.h, psi/iapi.c, psi/iapi.h, psi/idisp.c, psi/idisp.h. + The new DLL interface (new as of 7.0) is especially useful with the new display device, so it is included here. Both are due to Russell Lang. + +Troubleshooting +------------------------- + +The Ghostscript code has many tracing and debugging features that can be enabled at run time using the -Z command line switch, if the executable was compiled with ``DEBUG`` defined. One particularly useful combination is ``-Z@\?``, which fills free memory blocks with a pattern and also turns on run-time memory consistency checking. For more information, see doc/Use.htm#Debugging; you can also search for occurrences of ``if_debug`` or ``gs_debug_c`` in the source code. Note that many of these features are in the graphics library and do not require a PostScript interpreter. + +The code also contains many run-time procedures whose only purpose is to be called from the debugger to print out various data structures, including all the procedures in psi/idebug.c (for the PostScript interpreter) and the ``debug_dump_`` procedures in base/gsmisc.c. + +Files: + doc/Use.htm#Debugging, base/gdebug.h, base/gsmdebug.h, psi/idebug.h, psi/idebug.c. + + +Profiling +------------------------- + + +Profiling with Microsoft Developer Studio 6 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Microsoft profiling tool is included into Microsoft Developer Studio 6 Enterprise Edition only. Standard Edition and Professional Edition do not include it. + +Microsoft profiler tool requires the application to be linked with a special linker option. To provide it you need the following change to gs/base/msvccmd.mak: + + +.. code-block:: bash + + *** SVN-GS\HEAD\gs\src\msvccmd.mak Tue Jan 9 21:41:07 2007 + --- gs\src\msvccmd.mak Mon May 7 11:29:35 2007 + *************** + *** 159,163 **** + # Note that it must be followed by a space. + CT=/Od /Fd$(GLOBJDIR) $(NULL) $(CDCC) $(CPCH) + ! LCT=/DEBUG /INCREMENTAL:YES + COMPILE_FULL_OPTIMIZED= # no optimization when debugging + COMPILE_WITH_FRAMES= # no optimization when debugging + --- 159,164 ---- + # Note that it must be followed by a space. + CT=/Od /Fd$(GLOBJDIR) $(NULL) $(CDCC) $(CPCH) + ! # LCT=/DEBUG /INCREMENTAL:YES + ! LCT=/DEBUG /PROFILE + COMPILE_FULL_OPTIMIZED= # no optimization when debugging + COMPILE_WITH_FRAMES= # no optimization when debugging + *************** + *** 167,175 **** + !if $(DEBUGSYM)==0 + CT= + ! LCT= + CMT=/MT + !else + CT=/Zi /Fd$(GLOBJDIR) $(NULL) + ! LCT=/DEBUG + CMT=/MTd + !endif + --- 168,178 ---- + !if $(DEBUGSYM)==0 + CT= + ! # LCT= + ! LCT=/PROFILE + CMT=/MT + !else + CT=/Zi /Fd$(GLOBJDIR) $(NULL) + ! # LCT=/DEBUG + ! LCT=/DEBUG /PROFILE + CMT=/MTd + !endif + + +.. note :: + + Any of debug and release build may be profiled. + +Microsoft Profiler tool can't profile a dynamically loaded DLLs. When building Ghostscript with makefiles you need to specify ``MAKEDLL=0`` to nmake command line. + +The Integrated Development Environment of Microsoft Developer Studio 6 cannot profile a makefile-based project. Therefore the profiling tool to be started from command line. + +The profiling from command line is a 4 step procedure. The following batch file provides a sample for it : + + +.. code-block:: bash + + set DEVSTUDIO=G:\Program Files\Microsoft Visual Studio + set GS_HOME=..\..\gs-hdp + set GS_COMMAND_LINE=%GS_HOME%\bin\gswin32c.exe -I%GS_HOME%\lib;f:\afpl\fonts -r144 -dBATCH -dNOPAUSE -d/DEBUG attachment.pdf + set START_FUNCTION=_main + set Path=%DEVSTUDIO%\Common\MSDev98\Bin;%DEVSTUDIO%\VC98\Bin + PREP.EXE /OM /SF %START_FUNCTION% /FT %GS_HOME%\bin\gswin32c.exe + If ERRORLEVEL 1 echo step 1 fails&exit + PROFILE /I %GS_HOME%\bin\gswin32c.pbi %GS_COMMAND_LINE% + If ERRORLEVEL 1 echo step 2 fails&exit + PREP /M %GS_HOME%\bin\gswin32c /OT xxx.pbt + If ERRORLEVEL 1 echo step 3 fails&exit + PLIST /ST xxx.pbt >profile.txt + If ERRORLEVEL 1 echo step 4 fails&exit + +This batch file to be adopted to your configuration : + +- Edit the path to developer studio in the line 1. +- Edit the Ghostscript home directory in the line 2. +- Edit Ghostscript command line in line 3. Note that profiling without ``/NOPAUSE`` is a bad idea. +- In the line 4 edit the function name to start the profiling from. The sample code specifies ``_main`` as the starting function. Note it is the linker's function name, which starts with underscore. +- Edit the output file name in the line 5. + + + + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/DeviceSubclassing.rst b/doc/src/DeviceSubclassing.rst new file mode 100644 index 00000000..e53ef637 --- /dev/null +++ b/doc/src/DeviceSubclassing.rst @@ -0,0 +1,549 @@ +.. title:: Device Subclassing + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _DeviceSubclassing.htm: + + +Device Subclassing +========================================== + + + + + + +Devices in the graphics state +-------------------------------- + +The 'device' is a member of the graphics state in PostScript, and is subject to gsave/grestore, like any other part of the graphics state. This is important for PostScript as it allows us to, for example, push the null device, perform some operations, and then grestore back to the original rendering device. + +In PostScript and PDF, the graphics state is itself a garbage collected object, as is the device. This means that we store a pointer to the device in the graphics state, which forces the other interpreters to do so as well. Now an important implication of this is that it is then only possible, currently, to change devices by altering the graphics state entry to point at a different device structure, which means that the graphics state must be available in order to do so. Clearly at the interpreter level this isn't a problem, but at lower levels the graphics state may not be available, not all our device methods pass on a graphics state pointer for example. Without that pointer we can't change the graphics state and therefore can't point at a different device. + + + +Chaining devices +-------------------------------- +There are times when it is useful to be able to chain devices one after another, examples include the PDF transparency device, the pattern accumulator device and others. Some comments in early code indicate that the ability to chain devices was an original design goal, though its likely that originally this was only intended to work by installing devices from the interpreter level. + +Currently there are a number of different ways to install devices, and the sheer number, and the methods themselves, show why there is a problem. Lets consider them separately. + +- Forwarding devices. These devices generally intercept the usual graphics marking operations, and pass them on to the underlying device, or record some features of interest. Examples of these include the bbox device and the pattern accumulator. These work very well, but require the graphics state to be available when we need to insert them ahead of the 'underlying' device. This can be a problem, as we'll see later. + +- The device filter stack. This appears to be an early attempt at providing a way to chain devices together. From traces remaining in the code this seems to originally have been intended to implement the PDF 1.4 transparency rendering. Its clear, however, that it is no longer used for that purpose and appears to be completely redundant. In any event it also requires access to the graphics state and so would suffer the same limitation. + +- The clist. The clist code uses a very brute force approach to the problem, and only works for a single device. When a device is turned into a clist device, the code essentially guts the device and rewrites it (it replaces the overwritten entries later). This does work (though it seems rather horrendous to me) and doesn't require access to the graphics state because we simply reuse the existing memory of the original device. However this doesn't get us a 'chain', the clist simply morphs the existing device into something different. + +- The PDF transparency compositor. This works in several ways to install itself, but the one of most interest is the case where we return from the device 'create_compositor' method. The interpreter is required to treat the return value as a pointer to a device, and if its not the same as the device currently in the graphics state, then it alters the graphics state to point to the new device. I'm not sure why its done this way as we do actually have access to the graphics state in this method and could presumably install the device ourselves. However it is not useful as a general purpose method for installing devices as it requires the return value to be acted upon by the interpreter. Making this general would require us to modify all the existing device methods, and have the interpreters check the return value, it would almost certainly be simpler (and more useful) to alter the methods to always include a graphics state. + +- The 'spy' device. This is a somewhat non-standard device written by Robin, it works by copying the pointer to the device methods, and then replacing all the device methods, it is thus very similar to the clist device. + + + +Taken together we have a number of different routes to install devices, but none of them is totally satisfactory for the goal of creating a chain of devices without access to the graphics state. However I think the existence of these manifold routes do indicate that there has been a recognition in the past that this would be useful to have. + + +Subclassing +------------------ + +From the above, its clear that we need to use some approach similar to the clist and spy devices. We must retain the original device memory, because that is what the graphics state points to, which means that we must reuse that memory in some fashion. By making a copy of the existing device elsewhere, we can then recycle the existing device. + +As a short summary, that's precisely what the device subclassing code does. It examines the existing device, makes a new device structure sufficiently large to take a copy of it, and copies the existing device and all its state to that new memory. It then uses the prototype supplied for the new class, and writes that into the original device memory. + +New device members +~~~~~~~~~~~~~~~~~~~~ + +In order to chain the devices together, I've added three new pointers to the device structure (so that all devices can be chained), a child, a parent and a 'data' pointer (see below). Whenever we subclass a device the copied device gets its parent member set to the original device pointer, and the new device points to the copied one using the child member. + +Now a subtle point here is that, because we cannot change the size of the memory allocated for the original device (as that might relocate it, invalidating the graphics state pointer) its absolutely vital that the new device must be no larger than the old device. This means we have to be careful about data which the new device needs, we can't simply store it in the device structure as we usually do. To resolve that I've also added a void pointer to hold private data, the new device should allocate as much data as it requires (eg a structure) and store a pointer to that data in the subclass_data pointer. I'd recommend that this is allocated from non-GC memory except in special cases. This should mean that subclassing devices are never larger than a gx_device structure and so never overflow. + +Subclassing made easy +~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to minimise the number of methods that a subclassing device needs to define I've created 'default' methods for all the possible device methods. Subclassing devices should use these in their prototype for any methods they don't handle. Additionally these can be used to pass on any methods after processing by the subclassing device, if required. + + + +Example uses +----------------- + +The original justification for this work was to create a device which would add 'first page' and 'last page' functionality to all the languages and all the devices. The gdevflp.c file incorporates exactly that, it has been added to gdevprn.c and gdevvec.c so that any device based on either of these two basic devices will simply work. Additionally other devices which are not based on either of these (eg the 'bit' device) have been appropriately modified. + +If ``-dFirstPage`` or ``-dLastPage`` is set the parameter is parsed out and the existing device is subclassed by the new First/Last page device. This device simply drops all marking operations, and 'output_page' operations until we reach the page defined by FirstPage, and then passes everything through to the real device until we pass the page defined by ``LastPage`` at which point it throws everything away again until the end of the input. + +Now, this is not as efficient as the PDF interpreter's usage, which only passes those pages required to be rendered. So the old functionality has been preserved in the PDF interpreter, exactly as before. In order to prevent the subclassing device addionally acting on the same parameters, there is a ``DisablePageHandler`` flag which is set by the PDF interpreter. + +In order to test the chaining of devices together, I also created an 'object filtering' device; as with the first/last page device this has been added to all devices and any device based off gdevprn or gdevvec should inherit the functionality directly. This device allows objects to be dropped based on their type (text, image or linework) using the parameters ``-dFILTERTEXT`` ``-dFILTERIMAGE`` and ``-dFILTERVECTOR``, if a parameter is set then objects of that type will not be rendered. + +Finally the PCL interpreter now uses a subclassing device to implement the 'monochrome palette' rendering. Previously this directly modified the ``color_procs`` in the current device, which I suspect was prone to potential failure (for example if a forwarding device had been pushed). This eliminated a somewhat ugly hack (in fairness its not obvious what would have been better), as well as allowing me to do away with some global variables in the PCL interpreter. + + + +Observations +--------------- + +The monochrome palette device illuminated an interesting problem in the graphics library. Normally the device calls the graphics library for rendering services, but the ``color_procs`` work in reverse, the graphics library calls the device directly in order to map the colours. In the case of chained devices this meant that only the final device was being called. This was unacceptable in a situation involving chained devices, it seemed obvious to me that the graphics library should pass the request to the head of the device chain for processing. There is no simple way to do this (no access to the graphics state!) so instead I used the linked list of child/parent pointers to walk up to the head of the list, and then submit the request to that device. + +The ICC profile code has a ``get_profile`` method in the device API to retrieve a profile, but it has no corresponding ``set_profile`` method, it simply sets the structure member in the current device. This caused some serious problems. Consider the case where the ICC code executes a ``get_profile`` and no profile is yet set (returning NULL). The code would then create a profile and attach it directly to the current device. It then executes ``get_profile`` again. If the current device was a subclassing device, or a forwarding device, then the 'set' would have set the profile in that device, but the 'get' would retrieve it from the underlying device, which would still be NULL. Since the ICC code didn't test the result on the second call this caused a segmentation fault. I've modified the ICC code to set the profile in the lowest device, but this probably ought to be improved to define a new ``set_profile`` method. + +The tag devices write an extra colour plane in the output, where the value of the sample encodes the type of graphic that was rendered at that point (text, image, path, untouched or unknown). This is done by encoding the type in the color, which is performed by the graphics library. Now, when the type of operation changes (eg from image to text) we need to tell the graphics library that there has been a change. We do this by calling the ``set_graphics_type_tag`` device method. However, when encoding a color, the graphics library does not, as one might expect call a matching ``get_graphics_type`` method, instead it directly inspects the devcie structure and reads the ``graphics_type_tag`` member. This means that all devices in the chain must maintain this member, the implication is that if a subclassing device should implement its own ``set_graphics_type_tag`` method, it must update the ``graphics_type_tag`` in its device structure appropriately, and pass the method on to the next device in the chain. The default method already does this. + +Its pretty clear from reading through the code that the original intention of the device methods is that all methods in a device should be filled in, they should never be NULL (exception; ``fill_rectangle`` is deliberately excluded from this) if a device does not implement a method then ``fill_in_procs`` should set a default method (which may legitimately simply throw an error). Over time this decision has not been enforced with the result that we now have some places where methods may be NULL. This has meant that there are places in the code which have to check for a method being NULL before using it, which is (I think) exactly what we were originally trying to avoid. Worse, since there is no list of which methods may be NULL a sensible developer would have to test all methods before use. Worst of all, it looks like some places may take a NULL method as having specific meaning (``gsdparam.c`` line 272). We should really tidy this up. + +General observations are recorded in comments in ``gdevsclass.c``. + + +Worked example +--------------- + +To see how to use the device subclassing we'll take a concrete example and implement it in a real device. For the purposes of the example we'll do a 'force black text' device and add it to the TIFF device(s). The reason for choosing the TIFF devices is that these already have an ``open_device`` method which we are going to use to install the subclassing device. This isn't essential, you could install the device at any point, but its convenient. + +The first thing we need to do is add some control to turn this feature off and on, this is normally done by setting device parameters on the command line. To implement this we will need to modify the ``put_params`` and ``get_params`` methods. Note it is important to add new parameters to both the get and put methods, or an error will occur. We'll call our new parameter ``ForceBlackText``. + +First we add the new parameter to the TIFF device, defined in ``gdevtifs.h``: + + +.. code-block:: c + + typedef struct gx_device_tiff_s { + gx_device_common; + gx_prn_device_common; + bool ForceBlackText; + bool BlackTextHandlerPushed; + .... + } + +Note that we also have a boolean value ``BlackTextHandlerPushed`` to track whether the device is already pushed or not, we'll want to use this later. + +We also need to add default values to the device prototypes, which are defined in ``gdevtfnx.c``: + + +.. code-block:: c + + const gx_device_tiff gs_tiff12nc_device = { + prn_device_std_body(gx_device_tiff, tiff12_procs, "tiff12nc", + DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, + X_DPI, Y_DPI, + 0, 0, 0, 0, + 24, tiff12_print_page), + 0, /* ForceBlacktext */ + 0, /* BlacktextHandlerPushed */ + arch_is_big_endian /* default to native endian (i.e. use big endian iff the platform is so*/, + + +Repeat for ``gs_tiff24nc_device`` and ``gs_tiff48nc_device``. For unknown reasons, the remaining TIFF devices are in ``gdevtsep.c``, we need to make the same changes to the prototypes there; ``gs_tiffgray_device`` ``gs_tiffscaled_device`` ``gs_tiffscaled8_device`` ``gs_tiffscaled24_device`` ``gs_tiffscaled32_device`` ``gs_tiffscaled4_device`` ``gs_tiff32nc_device`` ``gs_tiff64nc_device`` and finally ``tiffsep_devices_body``. + +Now we add code to ``put_params`` and ``get_params`` to set the parameter, and report its value back to the interpreter. In ``gdevtifs.c``: + + +.. code-block:: c + + static int tiff_get_some_params(gx_device * dev, gs_param_list * plist, int which) + { + gx_device_tiff *const tfdev = (gx_device_tiff *)dev; + int code = gdev_prn_get_params(dev, plist); + int ecode = code; + gs_param_string comprstr; + + if ((code = param_write_bool(plist, "ForceBlackText", &tfdev->ForceBlackText)) < 0) + ecode = code; + .... + } + + static int tiff_put_some_params(gx_device * dev, gs_param_list * plist, int which) + { + gx_device_tiff *const tfdev = (gx_device_tiff *)dev; int ecode = 0; + int code; + const char *param_name; + bool big_endian = tfdev->BigEndian; + bool usebigtiff = tfdev->UseBigTIFF; + uint16 compr = tfdev->Compression; + gs_param_string comprstr; + long downscale = tfdev->DownScaleFactor; + long mss = tfdev->MaxStripSize; + long aw = tfdev->AdjustWidth; + long mfs = tfdev->MinFeatureSize; + bool ForceBlackText = tfdev->ForceBlackText; + + /* Read ForceBlackText option as bool */ + switch (code = param_read_bool(plist, (param_name = "ForceBlackText"), &ForceBlackText)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + + /* Read BigEndian option as bool */ + switch (code = param_read_bool(plist, (param_name = "BigEndian"), &big_endian)) { + ... + tfdev->MinFeatureSize = mfs; + tfdev->ForceBlackText = ForceBlackText; + return code; + } + } + + +Checking the TIFF device's open method (tiff_open) we see that it already potentially has two subclassing devices, this is because it doesn't inherit from ``gdev_prn``, if it did this functionality would be inherited as well. We can just go ahead and add our new subclassing device in here. + + +.. code-block:: c + + int tiff_open(gx_device *pdev) + { + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + gx_device_tiff *tfdev = (gx_device_tiff *)pdev; + int code; + bool update_procs = false; + + /* Use our own warning and error message handlers in libtiff */ + tiff_set_handlers(); + + if (!tfdev->BlackTextHandlerPushed && (tfdev->ForceBlackText != 0)) { + gx_device *dev; + + gx_device_subclass(pdev, (gx_device *)&gs_black_text_device, sizeof(black_text_subclass_data)); + tfdev = (gx_device_tiff *)pdev->child; + tfdev->BlackTextHandlerPushed = true; + + while(pdev->child) + pdev = pdev->child; + pdev->is_open = true; + update_procs = true; + } + + +You might notice that this is a little simpler than the other device installations, that's because the other devices can potentially be installed by any device, and we need to track them more carefully. Our new device can only be installed by the TIFF device, so we don't need to note that its been installed already, in all the parent and child devices. This is only done so that we don't accidentally install these more basic devices more than once. + +So the first thing we do is check to see if we've already installed the device to force black text (we can potentially call the open method more than once and we don't want to install the device multiple times). If we haven't installed the device yet, and the feature has been requested, then we call the code to subclass the current device using the ``black_text_device`` as the prototype for the new device, and pass in the amount of data it requires for its private usage. + +We will be defining this device as the next steps, for now just notice that after we call this, the 'current' device in the graphics state will be the ``black_text_device``, and its 'child' member will be pointing to the TIFF device. So we note in that child device that we have pushed the black text handling device. We also note that the TIFF device is 'open' (the calling code will do this for the device pointed to by the graphics state, i.e. the black text device). Finally we set a boolean to 'update procs'. This is needed because the ``tiff_open`` routine calls ``gdev_prn_allocate_memory`` which resets the device methods, we need to put them back to be correct for our device(s), which is done at the end of the ``tiff_open`` code: + + +.. code-block:: c + + if (update_procs) { + if (pdev->ObjectHandlerPushed) { + gx_copy_device_procs(&pdev->parent->procs, &pdev->procs, (gx_device_procs *)&gs_obj_filter_device.procs); + pdev = pdev->parent; + } + if (pdev->PageHandlerPushed) { + gx_copy_device_procs(&pdev->parent->procs, &pdev->procs, (gx_device_procs *)&gs_flp_device.procs); + pdev = pdev->parent; + } + /* set tfdev to the bottom device in the chain */ + tfdev = (gx_device_tiff *)pdev; + while (tfdev->child) + tfdev = (gx_device_tiff *)tfdev->child; + if (tfdev->BlackTextHandlerPushed) + gx_copy_device_procs(&pdev->parent->procs, &pdev->procs, (gx_device_procs *)&gs_black_text_device.procs); + } + +In essence this simply works backwards through the chain of devices, restoring the correct methods as it goes. Note that because the ``BlackTextHandlerPushed`` variable isn't defined in the basic device structure, we have to cast the device pointer to a ``gx_device_tiff *`` so that we can set and check the variable which is defined there. + +That completes the changes we need to make to the TIFF device to add support for our new code. Now we need to create the ``black_text`` device which will do the actual work. + +We don't need any extras in the device structure, so we'll just define our subclassing device as being a ``gx_device``: + + +.. code-block:: c + + /* Black Text device */ + typedef struct gx_device_s gx_device_black_text; + +We also don't need any extra storage, but we do need to carry round the basic storage required by a subclassing device, so we do need to define a structure for that: + + +.. code-block:: c + + typedef struct { + subclass_common; + } black_text_subclass_data; + +Now, we are going to deal with text (obviously) and text, like images, is handled rather awkwardly in the current device interface. Instead of the interpreter calling the various device methods, the ``text_begin`` method creates a text enumerator which it returns to the interpreter. The text enumerator contains its own set of methods for dealing with text, and the interpreter calls these, thus bypassing the device itself. Since our subclassing requires us to pass down a chain of devices, when dealing with text and images we must also implement a chain of enumerators. For subclassing devices which don't process text or images this is catered for in the ``default_subclass_*`` methods, but in this case we need to handle the situation. + +We start by creating our own text enumerator structure: + +.. code-block:: c + + typedef struct black_text_text_enum_s { + gs_text_enum_common; + gs_text_enum_t *child; + } black_text_text_enum_t; + + +Here we have a structure which contains the elements common to all enumerators, and a pointer to the next enumerator in the chain, we'll fill that in later. + +Ghostscript uses several memory managers, but for PostScript and PDF objects we use a garbage collector. Because we may want to store pointers to garbage collected objects in the text enumerator, and our device, we need to make the garbage collector aware of them. This is because the garbage collector can relocate objects in memory, in order to do so safely it needs to update any pointers referencing those objects with the new location and so it needs to be told about those pointers. + +So, we define a garbage collector structure for the text enumerator: + +.. code-block:: c + + extern_st(st_gs_text_enum); + gs_private_st_suffix_add1(st_black_text_text_enum, black_text_text_enum_t, "black_text_text_enum_t", black_text_text_enum_enum_ptrs, black_text_text_enum_reloc_ptrs, st_gs_text_enum, child); + + +The macro ``extern_st`` simply defines the structure (``st_gs_text_enum``) as being of type ``gs_memory_struct_type_t``. We need this structure for the 'superstructure' defined below. + +The next macro ``gs_private_st_suffix_add1`` is one of a family of macros used to define structures for the garbage collector. These all end up defining the named structure as being of type ``gc_struct_data_t`` and fill in various members of that structure. In this case we are declaring that the structure: + + - Has one pointer to additional garbage collected objects (``add_1``) + - Its name is ``st_black_text_text_enum`` + - It is of type ``black_text_text_enum_t`` + - Has the readable name for error messages ``black_text_text_enum_t`` + - The routine to be called to enumerate the garbage collected pointers in the structure is ``black_text_text_enum_enum_ptrs`` + - The routine to be called when relocating garbage collcted objects pointed to by the structure is ``black_text_text_enum_reloc_ptrs`` + - The 'superstructure' (i.e. the structure type this is based on) is ``st_gs_text_enum``. This means that all the enumeration and relocation methods for any pointers in the 'common' text enumerator structure get handled by this structure. + - The one additional pointer to a garbage collected object is the 'child' member. + +The macro takes care of creating all the code we need to deal with this object, essentially it will create ``black_text_text_enum_enum_ptrs`` and ``black_text_text_enum_reloc_ptrs`` for us. + +So now we have to do a similar job for the actual device itself. We start by defining the enumeration and relocation routines for the structure. There are extensive macros for doing this, and we make use of some of them here. Explaining these is out of the scope of this document, but they are defined and easy to locate in the Ghostscript source tree. + +.. code-block:: c + + static + ENUM_PTRS_WITH(black_text_enum_ptrs, gx_device *dev); + return 0; /* default case */ + case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); + case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); + ENUM_PTRS_END + + static RELOC_PTRS_WITH(black_text_reloc_ptrs, gx_device *dev) + { + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); + }RELOC_PTRS_END + + +Essentially these simply tell the garbage collector that we are maintaining two pointers to garbage collected objects, the parent and child devices. Now we use those in the garbage collector 'structure descriptor' for the device. Note this is not the actual device structure, its the structure used by the garbage collector when dealing with the device. + + + +.. code-block:: c + + gs_public_st_complex_only(st_black_text_device, gx_device, "black_text", 0, black_text_enum_ptrs, black_text_reloc_ptrs, gx_device_finalize); + + +Again ``gs_public_st_complex_only`` is a macro, and its one of a family, these end up defining structures of type ``gs_memory_struct_t``. In this case we are declaring: + + - The structure type is named ``st_black_text_device`` + - The structure is of size ``gx_device`` (this only works because we don't need any other storage, otherwise we would have to define the device structure and pass that here). + - The human readable name for error messages is ``black_text`` + - We don't define a ``clear`` routine. + - The enumerator for GC objects is called ``black_text_enum_ptrs`` + - The relocator for GC objects is called ``black_text_reloc_ptrs`` + - We use the regular ``gx_device_finalize`` routine when freeing the object, we don't declare a special one of our own. + +Now we've got all the garbage collector machinery out of the way we can deal with the actual device itself. Because we're only interested in text, there's only one device method we want to handle, the ``text_begin`` method, so we start by prototyping that: + + +.. code-block:: c + + /* Device procedures */ + static dev_proc_text_begin(black_text_text_begin); + + + +Then we define the procedure to initialize the device procs: + +.. code-block:: c + + void black_text_init_dev_procs(gx_device *dev) + { + default_subclass_initialize_device_procs(dev); + + set_dev_proc(dev, text_begin, black_text_text_begin); + } + + +Then we define the actual device: + + +.. code-block:: c + + const gx_device_black_text gs_black_text_device = + { + std_device_dci_type_body(gx_device_black_text, 0, "black_text", &st_black_text_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + black_text_initialize_device_procs + }; + +The call to ``default_subclass_initialize_device_procs`` assigns the default methods for a subclassing device. We then override the ``text_begin`` method to our specific one. The main body of the macro is: + + +.. code-block:: c + + const gx_device_black_text gs_black_text_device = + { + std_device_dci_type_body(gx_device_black_text, 0, "black_text", &st_black_text_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + + +This simply defines an instance of the ``gx_device_black_text`` structure (which is simply a ``gx_device_s`` structure) initialised using a macro (yet another family of macros). Here we use the ``st_black_text_device`` structure descriptor we created above, and some dummy values for the resolution, colour depth etc. Since this device doesn't do rendering these values aren't useful and these defaults should be fine. + +Now, for text we need to fill in all the procedures in the text enumerator, we'll start by defining the ``resync`` method, and then use this as a template for most of the other methods in the text enumerator: + + +.. code-block:: c + + static int black_text_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom) { + black_text_text_enum_t *penum; + gs_text_enum_t * child = penum->child; + int code; + + code = child->procs->resync(child, pfrom); + gs_text_enum_copy_dynamic(pte, child, true); + return code; + } + + +The routine starts by casting the generic text enumerator to our specific type of text enumerator. From that we can get the child enumerator, and we simply pass the operation on directly to the child (remembering to pass the child enumerator as an argument, not our own one!). + +Now, on return it may be that the child has modified the contents of the enumerator, so we must copy anything that might have changed from the child enumerator to our own. That's what the ``gs_text_enum_copy_dynamic`` routine does. After that we simply return the saved return value. + +All the other routines are basically the same as this, we don't really want to do anything in the text enumeration so we just hand off the processing to the child. + + +.. code-block:: c + + static int black_text_text_process(gs_text_enum_t *pte) { + black_text_text_enum_t *penum = (black_text_text_enum_t *)pte; + gs_text_enum_t * child = penum->child; + int code; + + code = child->procs->process(child); + gs_text_enum_copy_dynamic(pte, child, true); + return code; + } + + static bool black_text_text_is_width_only(const gs_text_enum_t *pte) { + black_text_text_enum_t *penum = (black_text_text_enum_t *)pte; + gs_text_enum_t * child = penum->child; + int code; + + code = child->procs->is_width_only(child); + gs_text_enum_copy_dynamic((gs_text_enum_t *)pte, child, true); + return code; + } + + static int black_text_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth) { + black_text_text_enum_t *penum = (black_text_text_enum_t *)pte; + gs_text_enum_t * child = penum->child; + int code; + + code = child->procs->current_width(child, pwidth); + gs_text_enum_copy_dynamic((gs_text_enum_t *)pte, child, true); + return code; + } + + static int black_text_text_set_cache(gs_text_enum_t *pte, const double *pw, gs_text_cache_control_t control) { + black_text_text_enum_t *penum = (black_text_text_enum_t *)pte; + gs_text_enum_t * child = penum->child; + int code; + + code = child->procs->set_cache(child, pw, control); + gs_text_enum_copy_dynamic(pte, child, true); + return code; + } + + static int black_text_text_retry(gs_text_enum_t *pte) { + black_text_text_enum_t *penum = (black_text_text_enum_t *)pte; + gs_text_enum_t * child = penum->child; + int code; + + code = child->procs->retry(child); + gs_text_enum_copy_dynamic(pte, child, true); + return code; + } + + static void black_text_text_release(gs_text_enum_t *pte, client_name_t cname) { + black_text_text_enum_t *penum = (black_text_text_enum_t *)pte; + gs_text_enum_t * child = penum->child; + + child->procs->release(child, cname); + gx_default_text_release(pte, cname); + } + + +The 'release' method is very slightly different, because we need to free the enumerator, so we call ``gx_default_text_release``. + +Now, finally, we can define the ``text_begin`` device method, the first thing we do is a convenience, we define a ``gs_text_enum_procs`` instance which is initialised to point to all the text enumerator methods we defined above: + + +.. code-block:: c + + static const gs_text_enum_procs_t black_text_text_procs = { + black_text_text_resync, black_text_text_process, black_text_text_is_width_only, black_text_text_current_width, black_text_text_set_cache, black_text_text_retry, black_text_text_release + }; + +So on to the ``text_begin`` method: + +.. code-block:: c + + /* The device method which we do actually need to define. */ + int black_text_text_begin(gx_device *dev, gs_imager_state *pis, const gs_text_params_t *text, + gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gs_text_enum_t **ppte) + { + black_text_text_enum_t *penum; + int code; + gs_text_enum_t *p; + + rc_alloc_struct_1(penum, black_text_text_enum_t, &st_black_text_text_enum, memory, + return_error(gs_error_VMerror), "black_text_text_begin"); + penum->rc.free = rc_free_text_enum; + code = gs_text_enum_init((gs_text_enum_t *)penum, &black_text_text_procs, + dev, pis, text, font, path, pdcolor, pcpath, memory); + if (code < 0) { + gs_free_object(memory, penum, "black_text_text_begin"); + return code; + } + *ppte = (gs_text_enum_t *)penum; + + code = default_subclass_text_begin(dev, pis, text, font, path, pdcolor, pcpath, memory, &p); + if (code < 0) { + gs_free_object(memory, penum, "black_text_text_begin"); + return code; + } + penum->child = p; + + return 0; + } + + +This uses library macros to create and initialise the text enumerator. Text enumerators are reference counted (and garbage collected.....) so we use the ``rc_alloc_struct`` family of macros, the '1' is the initial reference count that we want to have. We then call ``gs_text_enum_init`` to initialise the newly created structure, passing in the text procs we just created as one of the arguments. + +We then set the returned enumerator to point to the newly created text enumerator. Finally we pass the ``text_begin`` method on to the child device using the ``default_subclass_text_begin`` method and we store the returned text enumerator in the child pointer of our own enumerator. + +At this point the code should compile and run properly, but it won;t actually do anything yet. For that we need to modify the current colour before we run the text. Fortunately we don't need to deal with the graphics state, the ``text_begin`` method is given the colour index to be used so all we need to do is alter that. We do, however, have to cater for what the device thinks 'black' actually is, but there are graphics library calls to deal with both finding that information and setting a colour index from it: + + +.. code-block:: c + + int black_text_text_begin(gx_device *dev, gs_imager_state *pis, const gs_text_params_t *text, + gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gs_text_enum_t **ppte) + { + black_text_text_enum_t *penum; + int code; + gs_text_enum_t *p; + + /* Set the colour index in 'pdcolor' to be whatever the device thinks black shoudl be */ + set_nonclient_dev_color((gx_device_color *)pdcolor, gx_device_black((gx_device *)dev)); + + + + + + +.. include:: footer.rst diff --git a/doc/src/Devices.rst b/doc/src/Devices.rst new file mode 100644 index 00000000..90b26362 --- /dev/null +++ b/doc/src/Devices.rst @@ -0,0 +1,1333 @@ +.. title:: Details of Ghostscript Output Devices + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Devices.htm: + + +Details of Ghostscript Output Devices +============================================= + + +For other information, see the :ref:`Ghostscript overview<Ghostscript Introduction>`. You may also be interested in :ref:`how to build Ghostscript<Make.htm>` and :ref:`install<Install.htm>` it, as well as the description of the :ref:`driver interface<Drivers.htm>`. + +Documentation for some older, superceded devices has been moved to :ref:`unsupported devices<UnsupportedDevices.htm>`. In general such devices are deprecated and will be removed in future versions of Ghostscript. In general all older printer drivers can be replaced by the :title:`ijs` interface and one of the available 3rd party raster driver collections. We recommend moving to the :title:`ijs` device for all such printing. + + +Documentation for device subclassing can be found on the :ref:`Device Subclassing<DeviceSubclassing.htm>` page. + + +.. _Devices_Notes on measurements: + +Notes on measurements +---------------------------------------------- + +Several different important kinds of measures appear throughout this document: :ref:`inches<Inches>`, :ref:`centimeters and millimeters<Centimeters and millimeters>`, :ref:`points<Points>`, :ref:`dots per inch<Dots per inch>` and :ref:`bits per pixel<Bits per pixel>`. + + + +Inches +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 1 inch equals 2.54 centimeters. The inch measure is sometimes represented by in or a quotation mark (") to the right of a measure, like 8.5in or 8.5". U.S. "letter" paper is exactly 8.5in×11in, approximately 21.6cm×27.9cm. (See in the usage documentation all the :ref:`paper sizes predefined in Ghostscript<Known Paper Sizes>`.) + + + +Centimeters and millimeters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ISO standard paper sizes such as A4 and A3 are commonly represented in the SI units of centimeters and millimeters. Centimeters are abbreviated cm, millimeters mm. ISO A4 paper is quite close to 210×297 millimeters (approximately 8.3×11.7 inches). + + + +Points +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Points are a measure traditionally used in the printing trade and now in PostScript, which specifies exactly 72 points per inch (approximately 28.35 per centimeter). The :ref:`paper sizes known to Ghostscript<Known Paper Sizes>` are defined in the initialization file ``gs_statd.ps`` in terms of points. + + + +Dots per inch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Dots per inch or "dpi" is the common measure of printing resolution in the US. + + + +Bits per pixel +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Commonly abbreviated "bpp" this is the number of digital bits used to represent the color of each pixel. This is also referred to as 'bit depth' or 'pixel depth'. + + + + +Image file formats +---------------------------------------------- + +Ghostscript supports output to a variety of image file formats and is widely used for rasterizing postscript and pdf files. A collection of such formats ('output devices' in Ghostscript terminology) are described in this section. + +Here are some commonly useful driver options that apply to all raster drivers. Options specific to particular file formats are described in their respective sections below. + +.. code-block:: bash + + -sOutputFile=filename + +This is a general option telling Ghostscript what to name the output. It can either be a single filename 'tiger.png' or a template 'figure-%03d.jpg' where the %03d is replaced by the page number. + +.. code-block:: bash + + -rres + -rxresxyres + +This option sets the resolution of the output file in dots per inch. The default value if you don't specify this options is usually 72 dpi. + +.. code-block:: bash + + -dTextAlphaBits=n + -dGraphicsAlphaBits=n + +These options control the use of subsample antialiasing. Their use is highly recommended for producing high quality rasterizations of the input files. The size of the subsampling box n should be 4 for optimum output, but smaller values can be used for faster rendering. Antialiasing is enabled separately for text and graphics content. + +Because this feature relies upon rendering the input it is incompatible, and will generate an error on attempted use, with any of the vector output devices. + + +It is also conventional to call Ghostscript with the ``-dSAFER -dBATCH -dNOPAUSE`` trio of options when rasterizing to a file. These suppress interactive prompts and enable some security checks on the file to be run. Please see the :ref:`Using Ghostscript<Use.htm>` section for further details. + + + +.. _Devices_PNG: + +PNG file format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PNG (pronounced 'ping') stands for Portable Network Graphics, and is the recommended format for high-quality images. It supports full quality color and transparency, offers excellent lossless compression of the image data, and is widely supported. Please see the `PNG website`_ for a complete description of the format. + +Ghostscript provides a variety of devices for PNG output varying by bit depth. For normal use we recommend :title:`png16m` for 24-bit RGB color, or :title:`pnggray` for grayscale. The :title:`png256`, :title:`png16` and :title:`pngmono` devices respectively provide 8-bit color, 4-bit color and black-and-white for special needs. The :title:`pngmonod` device is also a black-and-white device, but the output is formed from an internal 8 bit grayscale rendering which is then error diffused and converted down to 1bpp. + +The :title:`png16malpha` and :title:`pngalpha` devices are 32-bit RGBA color with transparency indicating pixel coverage. The background is transparent unless it has been explicitly filled. PDF 1.4 transparent files do not give a transparent background with this device. The devices differ, in that the :title:`pngalpha` device enables Text and graphics anti-aliasing by default. We now recommend that people use the :title:`png16malpha` device in preference, and achieve any required antialiasing via the ``DownScaleFactor`` parameter, as this gives better results in many cases. + +Options +"""""""""" + +The :title:`pngmonod`, :title:`png16m`, :title:`pnggray`, :title:`png16malpha` and :title:`pngalpha` devices all respond to the following: + + +.. code-block:: bash + + -dDownScaleFactor=integer + +This causes the internal rendering to be scaled down by the given (integer <= 8) factor before being output. For example, the following will produce a 200dpi output png from a 600dpi internal rendering: + +.. code-block:: bash + + gs -sDEVICE=png16m -r600 -dDownScaleFactor=3 -o tiger.png\ + examples/tiger.eps + + +The :title:`pngmonod` device responds to the following option: + +.. code-block:: bash + + -dMinFeatureSize=state (0 to 4; default = 1) + +This option allows a minimum feature size to be set; if any output pixel appears on its own, or as part of a group of pixels smaller than ``MinFeatureSize`` x ``MinFeatureSize``, it will be expanded to ensure that it does. This is useful for output devices that are high resolution, but that have trouble rendering isolated pixels. + +While this parameter will accept values from 0 to 4, not all are fully implemented. 0 and 1 cause no change to the output (as expected). 2 works as specified. Values of 3 and 4 are accepted for compatibility, but behave as for 2. + +The :title:`png16malpha` and :title:`pngalpha` devices respond to the following option: + +.. code-block:: bash + + -dBackgroundColor=16#RRGGBB (RGB color, default white = 16#ffffff) + +For the :title:`png16malpha` and :title:`pngalpha` devices only, set the suggested background color in the PNG bKGD chunk. When a program reading a PNG file does not support alpha transparency, the PNG library converts the image using either a background color if supplied by the program or the bKGD chunk. One common web browser has this problem, so when using ``<body bgcolor="CCCC00">`` on a web page you would need to use ``-dBackgroundColor=16#CCCC00`` when creating alpha transparent PNG images for use on the page. + + +Examples +"""""""""" + +Examples of how to use Ghostscript to convert postscript to PNG image files: + + +.. code-block:: bash + + gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -dGraphicsAlphaBits=4 \ + -sOutputFile=tiger.png examples/tiger.png + gs -dSAFER -dBATCH -dNOPAUSE -r150 -sDEVICE=pnggray -dTextAlphaBits=4 \ + -sOutputFile=doc-%02d.png doc.pdf + +In commercial builds, the :title:`png16m` device will accept a ``-dDeskew`` option to automatically detect/correct skew when generating output bitmaps. + + + +.. _Devices_JPG: + +JPEG file format (JFIF) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript includes output drivers that can produce jpeg files from postscript or pdf images. These are the :title:`jpeg` and :title:`jpeggray` devices. + +Technically these produce Independent JPEG Group JFIF (JPEG File Interchange Format) files, the common sort found on the web. + +Please note that JPEG is a compression method specifically intended for continuous-tone images such as photographs, not for graphics, and it is therefore quite unsuitable for the vast majority of page images produced with PostScript. For anything other than pages containing simple images the lossy compression of the jpeg format will result in poor quality output regardless of the input. To learn more about the distinction, consult a reference about uses and abuses of JPEG, such as the `JPEG FAQ`_. + + +Options +"""""""""""" + +The JPEG devices support several special parameters to control the JPEG "quality setting" (DCT quantization level). + +.. code-block:: bash + + -dJPEGQ=N (integer from 0 to 100, default 75) + +Set the quality level N according to the widely used IJG quality scale, which balances the extent of compression against the fidelity of the image when reconstituted. Lower values drop more information from the image to achieve higher compression, and therefore have lower quality when reconstituted. + +.. code-block:: bash + + -dQFactor=M (float from 0.0 to 1.0) + + +Adobe's QFactor quality scale, which you may use in place of ``JPEGQ`` above. The QFactor scale is used by PostScript's ``DCTEncode`` filter but is nearly unheard-of elsewhere. + +At this writing the default JPEG quality level of 75 is equivalent to ``-dQFactor=0.5``, but the JPEG default might change in the future. There is currently no support for any additional JPEG compression options, such as the other DCTEncode filter parameters. + + + + +Examples +"""""""""" + +You can use the JPEG output drivers -- :title:`jpeg` to produce color JPEG files and :title:`jpeggray` for grayscale JPEGs -- the same as other file-format drivers: by specifying the device name and an output file name, for example + +.. code-block:: bash + + gs -sDEVICE=jpeg -sOutputFile=foo.jpg foo.ps + + + +.. _Devices_PNM: + +PNM +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PNM (portable network map) family of formats are very simple uncompressed image formats commonly used on unix-like systems. They are particularly useful for testing or as input to an external conversion utility. + +A wide variety of data formats and depths is supported. Devices include :title:`pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw`. + + + +.. _Devices_TIFF: + +TIFF file formats +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +TIFF is a loose collection of formats, now largely superceded by PNG except in applications where backward compatibility or special compression is required. The TIFF file format is described in the TIFF 6.0 Specification published by Adobe Systems Incorporated. + + +.. note :: + + Due to the structure of the TIFF format, writing TIFF output requires that the target file be seekable. Writing to stdout, pipes or other similar stream is not supported. Attempting to do so will generate an error. + +There are two unrelated sets of TIFF drivers. There are five color TIFF drivers that produce uncompressed output: + + + +:title:`tiffgray` + Produces 8-bit gray output. + +:title:`tiff12nc` + Produces 12-bit RGB output (4 bits per component). + +:title:`tiff24nc` + Produces 24-bit RGB output (8 bits per component). + +:title:`tiff48nc` + Produces 48-bit RGB output (16 bits per component). + +:title:`tiff32nc` + Produces 32-bit CMYK output (8 bits per component). + +:title:`tiff64nc` + Produces 64-bit CMYK output (16 bits per component). + +:title:`tiffsep` + The :title:`tiffsep` device creates multiple output files: a single 32 bit composite CMYK file and multiple :title:`tiffgray` files, one for each separation (unless ``-dNoSeparationFiles`` is specified). If separation files are being produced and more than one page is being generated, the output file specification must include a format specifier (e.g ``-o outfile-%d.tif``) so that each page can have a uniquely named set of separation files. + + The default compression is ``lzw`` but this may be overridden by the ``-sCompression=`` option. + + The file specified via the ``OutputFile`` command line parameter will contain CMYK data. This data is based upon the CMYK data within the file plus an equivalent CMYK color for each spot color. The equivalent CMYK color for each spot color is determined using the alternate tint transform function specified in the ``Separation`` and :title:`devicen` color spaces. Since this file is created based upon having color planes for each colorant, the file will correctly represent the appearance of overprinting with spot colors. + + File names for the separations for the CMYK colorants are created by appending '.Cyan.tif', '.Magenta.tif' '.Yellow.tif' or '.Black.tif' to the end of the file name specified via the ``OutputFile`` parameter. File names for the spot color separation files are created by appending the Spot color name in '(' and ').tif' to the filename. + + Note that, while the name of the ink is case-sensitive, the filename may not be (depending on the Operating System), so if a spot name matches one of the process ink names, it will have the spot number included as part of the name (e.g. ``YELLOW0``). + + If desired the file names for the spot color separation files can be created by appending '.sn.tif' (where n is the spot color number, see below) to the end of the file name specified via the ``OutputFile`` parameter. This change is a compile time edit. To obtain this type of output the function ``create_separation_file_name`` in ``gdevtsep.c`` should be called with a true value for its ``use_sep_name`` parameter. + + The :title:`tiffsep` device will automatically recognize spot colors. In this case their order is determined by when they are found in the input file. The names of spot colors may be specified via the ``SeparationColorNames`` device parameters. + + Internally each spot color is assigned a spot color number. These numbers start with 0 for the first spot color. The spot color numbers are assigned in the same order as the names are printed to stderr (see below). This order also matches the ordering in the ``SeparationColorNames`` list, if this parameter is specified. The spot color numbers are not affected by the ``SeparationOrder`` parameter. + + If only a subset of the colorants for a file is desired, then the separations to be output can be selected via the ``SeparationOrder`` device parameter. When colorants are selected via the ``SeparationOrder`` parameter, the composite CMYK output contains the equivalent CMYK data only for the selected colorants. + + .. note:: + The composite CMYK output, because it uses the tint transformed colour equivalents for any spot colours (see Postscript Language Reference "Separation Color Spaces" and "DeviceN Color Spaces"), may not produce an accurate preview, if the job uses overprinting. + + The :title:`tiffsep` device also prints the names of any spot colors detected within a document to stderr, (stderr is also used for the output from the :title:`bbox` device). For each spot color, the name of the color is printed preceded by '%%SeparationName: '. This provides a simple mechanism for users and external applications to be informed about the names of spot colors within a document. + + Generally Ghostscript will support a maximum of 64 process and spot colors. The :title:`tiffsep` device the :title:`psdcmyk` device and the :title:`psdcmyk16` devices maintain rendered data in a planar form with a maximum of 64 planes set by the definition of ``GS_CLIENT_COLOR_MAX_COMPONENTS`` in the code. That is there can be up to 64 colorants accurately handled with overprint on a single page. If more than 64 colorants are encountered, those beyond 64 will be mapped to CMYK using the alternate tint transform. + + When rendering a PDF document, Ghostscript can deteremine prior to rendering how many colorants occur on a particular page. With Postscript, this is not possible in general. To optimize for this, when rendering Postscript, it is possible to specify at run-time the number of spot colorants you wish to have the device capable of handling using the ``-dMaxSpots=N`` command option, where N is the number of spot colorants that you wish to be able to handle and must be no more than the 64 minus the number of process colors. For example, 60 or less for a CMYK device such as tiffsep. If you specify more than is needed, the document will render more slowly. The ideal case is to use the same number as the maximum number of spot colorants that occur on a single page of the document. If more spot colorants are encountered than is specified by ``-dMaxSpots``, then a warning will be printed indicating that some spot colorants will be mapped to CMYK using the alternate tint transform. + + The tiffsep device accepts a ``-dBitsPerComponent=`` option, which may be set to 8 (the default) or 1. In 1bpp mode, the device renders each component internally in 8 bits, but then converts down to 1bpp with error diffusion before output as described below in the tiffscaled device. No composite file is produced in 1bpp mode, only individual separations. + + The device also accepts the ``-dDownScaleFactor= -dTrapX= -dTrapy=`` and ``-sPostRenderProfile=`` parameters as described below in the :title:`tiffscaled` device, and ``-dMinFeatureSize=`` in 1bpp mode. + + When ``-dDownScaleFactor=`` is used in 8 bit mode with the tiffsep (and :title:`psdcmyk`/:title:`psdrgb`/:title:`psdcmyk16`/:title:`psdrgb16`) device(s) 2 additional "special" ratios are available, 32 and 34. 32 provides a 3:2 downscale (so from 300 to 200 dpi, say). 34 produces a 3:4 upscale (so from 300 to 400 dpi, say). + + In commercial builds, with 8 bit per component output, the ``-dDeskew`` option can be used to automatically detect/correct skew when generating output bitmaps. + + The :title:`tiffscaled` and :title:`tiffscaled4` devices can optionally use Even Toned Screening, rather than simple Floyd Steinberg error diffusion. This patented technique gives better quality at the expense of some speed. While the code used has many quality tuning options, none of these are currently exposed. Any device author interested in trying these options should contact Artifex for more information. Currently ETS can be enabled using ``-dDownScaleETS=1``. + +:title:`tiffsep1` + The :title:`tiffsep1` device creates multiple output files, one for each component or separation color. The device creates multiple :title:`tiffg4` files (the compression can be set using ``-sCompression=`` described below). The 1 bit per component output is halftoned using the current screening set by 'setcolorscreen' or 'sethalftone' which allows for ordered dither or stochastic threshold array dither to be used. This is faster than error diffusion. + + The file specified via the ``OutputFile`` command line parameter will not be created (it is opened, but deleted prior to finishing each page). + + File names for the separations for the CMYK colorants are created by appending '(Cyan).tif', '(Magenta).tif' '(Yellow).tif' or '(Black).tif' to the to the end of the file name specified via the ``OutputFile`` parameter. File names for the spot color separation files are created by appending the ``Spot`` color name in '(' and ').tif' to the filename. If the file name specified via the ``OutputFile`` parameter ends with the suffix '.tif', then the suffix is removed prior to adding the component name in '(' and ').tif'. + +:title:`tiffscaled` + The :title:`tiffscaled` device renders internally at the specified resolution to an 8 bit greyscale image. This is then scaled down by an integer scale factor (set by ``-dDownScaleFactor=`` described below) and then error diffused to give 1bpp output. The compression can be set using ``-sCompression=`` as described below. + +:title:`tiffscaled4` + The :title:`tiffscaled4` device renders internally at the specified resolution to an 8 bit cmyk image. This is then scaled down by an integer scale factor (set by ``-dDownScaleFactor=`` described below) and then error diffused to give 4bpp cmyk output. The compression can be set using ``-sCompression=`` as described below. + +:title:`tiffscaled8` + The :title:`tiffscaled8` device renders internally at the specified resolution to an 8 bit greyscale image. This is then scaled down by an integer scale factor (set by ``-dDownScaleFactor=`` described below). The compression can be set using ``-sCompression=`` as described below. + +:title:`tiffscaled24` + The :title:`tiffscaled24` device renders internally at the specified resolution to a 24 bit rgb image. This is then scaled down by an integer scale factor (set by ``-dDownScaleFactor=`` described below). The compression can be set using ``-sCompression=`` as described below. + + In commercial builds, the ``-dDeskew`` option can be used to automatically detect/correct skew when generating output bitmaps. + +:title:`tiffscaled32` + The :title:`tiffscaled32` device renders internally at the specified resolution to a 32 bit cmyk image. This is then scaled down by an integer scale factor (set by ``-dDownScaleFactor=`` described below). The compression can be set using ``-sCompression=`` as described below. + + In commercial builds, the ``-dDeskew`` option can be used to automatically detect/correct skew when generating output bitmaps. + + +The remaining TIFF drivers all produce black-and-white output with different compression modes: + +:title:`tiffcrle` + G3 fax encoding with no EOLs. + +:title:`tiffg3` + G3 fax encoding with EOLs. + +:title:`tiffg32d` + 2-D G3 fax encoding. + +:title:`tiffg4` + G4 fax encoding. + +:title:`tifflzw` + LZW-compatible (tag = 5) compression. + +:title:`tiffpack` + PackBits (tag = 32773) compression. + +See the ``AdjustWidth`` option documentation below for important information about these devices. + + +Options +"""""""""""""""""""""""" + + +All TIFF drivers support creation of files that are comprised of more than a single strip. Multi-strip files reduce the memory requirement on the reader, since readers need only store and process one strip at a time. The ``MaxStripSize`` parameter controls the strip size: + + +.. code-block:: bash + + -dMaxStripSize=N + +Where **N** is a non-negative integer; default = 8192, 0 on Fax devices. Set the maximum (uncompressed) size of a strip. + + +The TIFF 6.0 specification, Section 7, page 27, recommends that the size of each strip be about 8 Kbytes. + +If the value of the ``MaxStripSize`` parameter is smaller than a single image row, then no error will be generated, and the TIFF file will be generated correctly using one row per strip. Note that smaller strip sizes increase the size of the file by increasing the size of the ``StripOffsets`` and ``StripByteCounts`` tables, and by reducing the effectiveness of the compression which must start over for each strip. + +If the value of ``MaxStripSize`` is 0, then the entire image will be a single strip. + +Since v. 8.51 the logical order of bits within a byte, ``FillOrder``, tag = 266 is controlled by a parameter: + + +.. code-block:: bash + + -dFillOrder=1 | 2 (default = 1) + +If this option set to 2 then pixels are arranged within a byte such that pixels with lower column values are stored in the lower-order bits of the byte; otherwise pixels are arranged in reverse order. + + +Earlier versions of Ghostscript always generated TIFF files with ``FillOrder = 2``. According to the TIFF 6.0 specification, Section 8, page 32, support of ``FillOrder = 2`` is not required in a Baseline TIFF compliant reader + +The writing of ``BigTIFF`` format output files is controlled with the ``-dUseBigTIFF`` parameter. + +Unfortunately, due the unpredictable size of compressed output, we cannot automate the selection of ``BigTIFF``, using it only when the output file grows large enough to warrant it. + +.. code-block:: bash + + -dUseBigTIFF(=false/true) (boolean, default: false) + + +Forces use (or not) of ``BigTIFF`` format in output from TIFF devices. + +The writing of the DateTime TAG can be controlled using the ``-dTIFFDateTime`` parameter. + +.. code-block:: bash + + -dTIFFDateTime(=true/false) (boolean, default: true) + +Write or otherwise the ``DateTime TAG`` to the TIFF output file. Thus to disable writing the ``TAG``, use: ``-dTIFFDateTime=false``. + +The compression scheme that is used for the image data can be set for all tiff devices with: + +.. code-block:: bash + + -sCompression=none | crle | g3 | g4 | lzw | pack + +Change the compression scheme of the tiff device. ``crle``, ``g3``, and ``g4`` may only be used with 1 bit devices (including :title:`tiffsep1`). + + + +For the :title:`tiffsep` device, it changes the compression scheme of the separation files and composite cmyk file (which is lzw by default). It defaults to ``g4`` for the :title:`tiffsep1` device. + +The black-and-white TIFF devices also provide the following parameters: + + +.. code-block:: bash + + -dAdjustWidth=state (0, 1, or value; default = 1) + +If this option is 1 then if the requested page width is in the range of either 1680..1736 or 2000..2056 columns, set the page width to A4 (1728 columns) or B4 (2048 columns) respectively. If this option is set to a value >1 then the width is unconditionally adjusted to this value. + +This behavior is the default for all the fax based devices (i.e. all the black and white devices except :title:`tifflzw`, :title:`tiffpack` and :title:`tiffscaled`). Pass ``-dAdjustWidth=0`` to force this behaviour off. + +When using this option with :title:`tiffscaled` it is the downsampled size that triggers the adjustment. + +.. code-block:: bash + + -dMinFeatureSize=state (0 to 4; default = 1) + +This option allows a minimum feature size to be set; if any output pixel appears on its own, or as part of a group of pixels smaller than ``MinFeatureSize`` x ``MinFeatureSize``, it will be expanded to ensure that it does. This is useful for output devices that are high resolution, but that have trouble rendering isolated pixels. + +While this parameter will accept values from 0 to 4, not all are fully implemented. 0 and 1 cause no change to the output (as expected). 2 works as specified. 3 and 4 currently expand pixels correctly horizontally, but only expand vertically to the 2 pixel size. + +The mechanism by which ``MinFeatureSize`` is implemented for :title:`tiffscaled` is different, in that it is done as part of the error diffusion. Values of 0 to 2 work as expected, but values 3 and 4 (while accepted for compatibility) will behave as for 2. + + +The :title:`tiffscaled`, :title:`tiffscaled4`, :title:`tiffscaled8`, :title:`tiffscaled24` and :title:`tiffscaled32` TIFF drivers also provide the following two parameters: + + +.. code-block:: bash + + -dDownScaleFactor=factor (integer <= 8; default = 1) + +If this option set then the page is downscaled by the given factor on both axes before error diffusion takes place. For example rendering with -r600 and then specifying ``-dDownScaleFactor=3`` will produce a 200dpi image. + +.. code-block:: bash + + -sPostRenderProfile=path (path to an ICC profile) + +If this option set then the page will be color transformed using that profile after downscaling. + +This is useful when the file uses overprint to separately paint to some subset of the C, M, Y, and K colorants, but the final CMYK is to be color corrected for printing or display. + + +The :title:`tiffsep` TIFF device also provide this parameter: + +.. code-block:: bash + + -dPrintSpotCMYK=boolean defaults to false. + +When set to true the device will print (to stdout) the name of each ink used on the page, and the CMYK values which are equivalent to 100% of that ink. The values are 16-bits ranging from 0 to 32760. + + +The :title:`tiffsep` device (along with the :title:`tiffscaled32` and :title:`psdcmyk` devices) can perform rudimentary automatic bitmap 'trapping' on the final rendered bitmap. This code is disabled by default; see the :ref:`note<TrappingPatentsNote>` below as to why. + +Trapping is a process whereby the output is adjusted to minimise the visual impact of offsets between each printed plane. Typically this involves slightly extending abutting regions that are rendered in different inks. The intent of this is to avoid the unsightly gaps that might be otherwise be revealed in the final printout if the different color plates do not exactly line up. + +This trapping is controlled by 3 device parameters. Firstly the maximum X and Y offsets are specified using ``-dTrapX=N`` and ``-dTrapY=N`` (where N is a figure in pixels, before the downscaler is applied). + +The final control is to inform the trapping process in what order inks should be processed, from darkest to lightest. For a typical CMYK device this order would be [ 3 1 0 2 ] (K darker than M darker than C darker than Y). This is the default. In the case where CMYK + spots are used, the code defaults to assuming that the spots are lighter than the standard colours and are sent darkest first (thus [ 3 1 0 2 4 5 6 ... ]). + +To override these defaults, the ``TrapOrder`` parameter can be used, for example: + +.. code-block:: bash + + gs -sDEVICE=psdcmyk -dTrapX=2 -dTrapY=2 -o out.psd -c "<< /TrapOrder [ 4 5 3 1 0 2 ] >> setpagedevice" -f examples\tiger.eps + + +.. _TrappingPatentsNote: + +.. note:: + + **Trapping patents**. Trapping is an technology area encumbered by many patents. We believe that the last of these has now lapsed, and so have enabled the code by default. + + +.. _Devices_FAX: + +FAX +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript supports a variety of fax encodings, both encapsulated in TIFF (see above) and as raw files. The later case is described here. + +The fax devices are :title:`faxg3`, :title:`faxg32d` and :title:`faxg4`. + +The fax devices support the ``MinFeatureSize`` parameter as defined in the TIFF device section. + +It appears from this commit: ``0abc209b8460396cdece8fc824c053a2662c4cbf`` that some (many ?) fax readers cannot cope with multiple strip TIFF files. The commit noted above works around this by assuming no fax output will exceed 1MB. Unfrotunately it also altered all the TIFF devices' default strip size which we now think was inadvisable. The fax devices now use a ``MaxStripSize`` of 0 so that the file only contains a single strip. This can still be overridden by specifying ``MaxStripSize`` on the command line. + + +.. _Devices_BMP: + +BMP +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +BMP is a simple uncompressed image format commonly used on MS Windows. + +It is supported by the :title:`bmpmono bmpgray bmpsep1 bmpsep8 bmp16 bmp256 bmp16m bmp32b` series of devices. + + +.. _Devices_PCX: + +PCX +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PCX is an image format sometimes used on MS Windows. It has some support for image compression and alternate color spaces, and so can be a useful way to output CMYK. + +It is supported by the :title:`pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk` series of devices. + + + +.. _Devices_PSD: + +PSD +~~~~~~~~~~~~~~~~~~~~ + +PSD is the image format used by Adobe Photoshop. + +It is supported by the :title:`psdcmyk psdrgb psdcmyk16 psdrgb16` series of devices. + +Of special interest with the :title:`psdcmyk` and :title:`psdcmyk16` devices is that they support spot colors. See the comments under the :title:`tiffsep` and :title:`tiffsep1` device about the maximum number of spot colors supported by Ghostscript. + +The :title:`psdcmyk16` and :title:`psdrgb16` devices are essentially the same as the :title:`psdcmyk` and :title:`psdrgb` devices except they provide 16 bit output. + +The :title:`psdcmykog` device produces PSD files with 6 components: Cyan, Magenta, Yellow, blacK, Orange, and Green. This device does not support the ``-dDownScaleFactor=`` option (see below), instead it always scales down by a factor of two. + +These devices support the same ``-dDownScaleFactor=`` ratios as :title:`tiffsep`. The :title:`psdcmyk` device supports the same trapping options as :title:`tiffsep` (but see :ref:`this note<TrappingPatentsNote>`). + + +.. note:: + + The PSD format is a single image per file format, so you must use the "%d" format for the ``OutputFile`` (or "-o") file name parameter (see :ref:`One page per file<Use_OnePagePerFile>` for details). An attempt to output multiple pages to a single PSD file (i.e. without the "%d" format) will result in an ``ioerror`` Postscript error. + +In commercial builds, for the :title:`psdcmyk` and :title:`psdrgb` devices, the ``-dDeskew`` option can be used to automatically detect/correct skew when generating output bitmaps. + + +.. _Devices_PDF: + +PDF +~~~~~~~~~~~~~~~~~~~~ + +These devices render input to a bitmap (or in the case of PCLm multiple bitmaps) then wraps the bitmap(s) up as the content of a PDF file. For PCLm there are some additional rules regarding headers, extra content and the order in which the content is written in the PDF file. + +The aim is to support the PCLm mobile printing standard, and to permit production of PDF files from input where the graphics model differs significantly from PDF (eg PCL and RasterOPs). + +There are five devices named :title:`pdfimage8`, :title:`pdfimage24`, :title:`pdfimage32`, :title:`pclm` and :title:`pclm8`. These produce valid PDF files with a colour depth of 8 (Gray), 24 (RGB) or 32 (CMYK), the :title:`pclm` device only supports 24-bit RGB and the :title:`pclm8` device only supports 8-bit gray. These are all implemented as 'downscale' devices, which means they can implement page level anti-aliasing using the ``-dDownScaleFactor`` switch. + + +.. code-block:: bash + + -dDownScaleFactor=integer + +This causes the internal rendering to be scaled down by the given (integer <= 8) factor before being output. For example, the following will produce a PDF containing a 200dpi output from a 600dpi internal rendering: + +.. code-block:: bash + + gs -sDEVICE=pdfimage8 -r600 -dDownScaleFactor=3 -o tiger.pdf\ + examples/tiger.eps + + + +In commercial builds, the ``-dDeskew`` option can be used to automatically detect/correct skew when generating the output file. + +The type of compression used for the image data can also be selected using the ``-sCompression`` switch. Valid compression types are ``None``, ``LZW``, ``Flate``, :title:`jpeg` and ``RLE``. + +.. note:: + + ``LZW`` is not supported on :title:`pclm` (not valid) and ``None`` is only supported on :title:`pclm` for debugging purposes. + +For JPEG compression the devices support both the JPEGQ and QFactor switches as documented for the JPEG file format device. + +In addition, the PCLm device supports some other parameters. Firstly, the ``-dStripHeight`` switch to set the vertical height of the strips of image content, as required by the specification. + +Secondly, the standard postscript ``-dDuplex`` and ``-dTumbleswitches`` are supported, in that if both are set to true, every verso page (i.e. all even pages) will be rotated by 180 degrees. + +As an extension to this, a ``-dTumble2`` parameter is also supported that will add an additional X-axis flip for every verso page. Thus ``-dDuplex=true -dTumble=false -dTumble2=true`` will result in verso pages being flipped horizontally, and ``-dDuplex=true -dTumble=true -dTumble2=true`` will result in verso pages being flipped vertically. + + + +.. note:: + + In addition to raster image files, Ghostscript supports output in a number of 'high-level' formats. These allow Ghostscript to preserve (as much as possible) the drawing elements of the input file maintaining flexibility, resolution independence, and editability. + + + +.. _Devices_OCR: + +Optical Character Recognition (OCR) devices +-------------------------------------------------------------------------------------------- + +OCR text output +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These devices render internally in 8 bit greyscale, and then feed the resultant image into an OCR engine. Currently, we are using the Tesseract engine. Not only is this both free and open source, it gives very good results, and supports a huge number of languages/scripts. + +The Tesseract engine relies on files to encapsulate each language and/or script. These "traineddata" files are available in different forms, including fast and best variants. Alternatively, people can train their own data using the standard Tesseract tools. + +These files are looked for from a variety of places. + +#. Files will be searched for in the directory given by the environment variable ``TESSDATA_PREFIX``. + +#. Then they will be searched for within the ROM filing system. Any files placed in "tessdata" will be included within the ROM filing system in the binary for any standard (``COMPILE_INITS=1``) build. + +#. Then files will be searched for in the configured 'tessdata' path. On Unix, this can be specified at the configure stage using '--with-tessdata=<path>' (where <path> is a list of directories to search, separated by ':' (on Unix) or ';' (on Windows)). + +#. Finally, we resort to searching the current directory. + +Please note, this pattern of directory searching differs from the original release of the OCR devices. + +By default, the OCR process defaults to looking for English text, using "eng.traineddata". This can be changed by using the ``-sOCRLanguage=`` switch: + +.. code-block:: bash + + -sOCRLanguage=language + +This sets the trained data sets to use within the Tesseract OCR engine. + +For example, the following will use English and Arabic: + +.. code-block:: bash + + gs -sDEVICE=ocr -r200 -sOCRLanguage="eng+ara" -o out.txt\ + zlib/zlib.3.pdf + + +The first device is named :title:`ocr`. It extracts data as unicode codepoints and outputs them to the device as a stream of UTF-8 bytes. + +The second device is named :title:`hocr`. This extracts the data in `hOCR`_ format. + +These devices are implemented as downscaling devices, so the standard parameters can be used to control this process. It may seem strange to use downscaling on an image that is not actually going to be output, but there are actually good reasons for this. Firstly, the higher the resolution, the slower the OCR process. Secondly, the way the Tesseract OCR engine works means that anti-aliased images perform broadly as well as the super-sampled image from which it came. + + +PDF image output (with OCR text) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These devices do the same render to bitmap and wrap as a PDF process as the ``PDFimage`` devices above, but with the addition of an OCR step at the end. The OCR'd text is overlaid "invisibly" over the images, so searching and cut/paste should still work. + +The OCR engine being used is Tesseract. For information on this including how to control what language data is used, see the OCR devices section above. + +There are three devices named :title:`pdfocr8`, :title:`pdfocr24` and :title:`pdfocr32`. These produce valid PDF files with a colour depth of 8 (Gray), 24 (RGB) or 32 (CMYK). + +These devices accept all the same flags as the PDFimage devices described above. + + + +Vector PDF output (with OCR Unicode CMaps) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :title:`pdfwrite` device has been augmented to use the OCR engine to analyse text (not images!) in the input stream, and derive Unicode code points for it. That information can then be used to create ``ToUnicode CMaps`` which are attached to the ``Font`` (or ``CIDFont``) objects embedded in the PDF file. + +Fonts which have ``ToUnicode CMaps`` can be reliably (limited by the accuracy of the ``CMap``) used in search and copy/paste functions, as well as text extraction from PDF files. Note that OCR is not a 100% perfect process; it is possible that some text might be misidentified. + +OCR is a slow operation! In addition it can (for Latin text at least) sometimes be preferable not to add ``ToUnicode`` information which may be incorrect, but instead to use the existing font ``Encoding``. For English text this may give better results. + +For these reasons the OCR functionality of :title:`pdfwrite` can be controlled by using a new parameter ``-sUseOCR``. This has three possible values: + +.. code-block:: bash + + -sUseOCR=string + +**string** values as follows: + +**Never** + Default - don't use OCR at all even if support is built-in. + +**AsNeeded** + If there is no existing ToUnicode information, use OCR. + +**Always** + Ignore any existing information and always use OCR. + + +.. _Devices_HighLevel: + + +High level devices +--------------------------------------------------------------------------------- + + +Please refer to :ref:`High Level Devices<VectorDevices.htm>` for documentation on the device options for these devices. + + + +PDF writer +~~~~~~~~~~~~~~~~~~~~ + +The :title:`pdfwrite` device outputs PDF. + +PS2 writer +~~~~~~~~~~~~~~~~~~~~ + +The :title:`ps2write` device outputs postscript language level 2. It is recommnded that this device is used for PostScript output. There is no longer any support for creating PostScript level 1 output. + + +EPS writer +~~~~~~~~~~~~~~~~~~~~ + +The :title:`eps2write` device outputs encapsulated postscript. + +PXL +~~~~~~~~~~~~~~~~~~~~ + +The :title:`pxlmono` and :title:`pxlcolor` devices output HP PCL-XL, a graphic language understood by many recent laser printers. + +Text output +~~~~~~~~~~~~~~~~~~~~ + +The :title:`txtwrite` device will output the text contained in the original document as Unicode. + + +.. _Devices_Display_Device: +.. _Devices_Display_Devices: + +Display devices +--------------------------- + +Ghostscript is often used for screen display of postscript and pdf documents. In many cases, a client or 'viewer' application calls the Ghostscript engine to do the rasterization and handles the display of the resulting image itself, but it is also possible to invoke Ghostscript directly and select an output device which directly handles displaying the image on screen. + +This section describes the various display-oriented devices that are available in Ghostscript. + + +X Window System +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Perhaps the most common use of of a display device is with the X Window System on unix-like systems. It is the default device on the command line client on such systems, and is used more creatively by the gv client application. + +The available devices are: + +:title:`x11` + This is the default device, handling display on X11R6. + +:title:`x11alpha` + This is the :title:`x11` device, but with antialiasing. It is equivalent to invoking the x11 device with the options ``-dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000``. + +:title:`x11cmyk` + This device rasterizes the image in the CMYK color space, then flattens it to RGB for display. It's intended for testing only. + +:title:`x11mono` + This is a strict black-and-white device for 1-bit monochrome displays. + +:title:`x11gray2` + This is a device for 2 bpp (4-level) monochrome displays. + +:title:`x11gray4` + This is a device for 4 bpp (16-level) monochrome displays. + +On Mac OS X as of 10.6, the X server (XQuartz) only supports color depth 15 and 24. Depth 15 isn't well-tested, and it may be desirable, for serious use, to switch to depth 24 with: + +.. code-block:: bash + + defaults write org.x.X11 depth 24 + + + +Display device (MS Windows, OS/2, gtk+) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The display device is used by the MS Windows, OS/2 and the gtk+ versions of Ghostscript. + + +Options +""""""""""""""" + +The display device has several user settable options. + + +``-dDisplayFormat=N (integer bit-field)`` + + Some common values are ``16#30804`` for Windows RGB, ``16#804`` for gtk+ RGB, ``16#20101`` for Windows monochrome, ``16#102`` for gtk+ monochrome, ``16#20802`` grayscale, ``16#20808`` for CMYK, ``16#a0800`` for separations. + + The bit fields are: + + - native (1), gray (2), RGB (4), CMYK (8), or separation (80000) color spaces. + - unused first byte (40) or last byte (80). + - 1 (100), 4 (400), or 8 (800) bits/component. + - bigendian (00000 = RGB) or littleendian (10000 = BGR) order. + - top first (20000) or bottom first (00000) raster. + - 16 bits/pixel with 555 (00000) or 565 (40000) bitfields. + - For more details, see the Ghostscript Interpreter API. + +``-dDisplayResolution=DPI`` + + Set the initial resolution resolution for the display device. This is used by the Windows clients to set the display device resolution to the Windows display logical resolution. This can be overriden by the command line option ``-rDPI``. + + + +When using the separation color space, the following options may be set using ``setpagedevice``, as described in the PostScript Language Reference: + +``SeparationColorNames`` + An array giving the names of the spot colors. + +``SeparationOrder`` + An array giving the names and order of the colorants to be output. + + + +IJS - Inkjet and other raster devices +--------------------------------------------------------------------------------- + +IJS is a relatively new initiative to improve the quality and ease of use of inkjet printing with Ghostscript. Using IJS, you can add new drivers, or upgrade existing ones, without recompiling Ghostscript. All driver authors are encouraged to adapt their drivers for IJS, and if there is an IJS driver available for your printer, it should be your first choice. + +Please see the IJS web page for more information about IJS, including a listing of IJS-compatible drivers. + +A typical command line for IJS is: + +.. code-block:: bash + + gs -dSAFER -sDEVICE=ijs -sIjsServer=hpijs -sDeviceManufacturer=HEWLETT-PACKARD -sDeviceModel='DESKJET 990' -dIjsUseOutputFD -sOutputFile=/dev/usb/lp1 -dNOPAUSE -- examples/tiger.eps + + +Individual IJS command line parameters are as follows: + + +``-sIjsServer={path}`` + Sets the pathname for the IJS server (ie printer driver). Ghostscript will spawn a new process for this driver, and communicate with it using the IJS protocol. The pathname need not be absolute, as the PATH environment variable is searched, but it's probably a good idea for robustness and security. Note also that if ``-dSAFER`` is not specified, it's possible for PostScript code to set this parameter, so it can cause arbitrary code to be executed. See the section on Security for more information. + +``-sDeviceManufacturer={name} -sDeviceModel={name}`` + These parameters select the device according to IEEE-1284 standard device ID strings. In general, consult the documentation for the driver to find the appropriate settings. Note that, if the value contains a space, you'll want to quote the value in your shell, as in the example above. + +``-sIjsParams={params}`` + This parameter allows you to set arbitrary IJS parameters on the IJS driver. The format is a comma-separated list of key=value pairs. If it is necessary to send a value containing a comma or backslash, it can be escaped with a backslash. Thus, ``-sIjsParams=Foo=bar,Baz=a\,b`` sets the parameter Foo to "bar", and Baz to "a,b". + +``-dIjsUseOutputFD`` + This flag indicates that Ghostscript should open the output file and pass a file descriptor to the server. If not set, Ghostscript simply passes the filename set in OutputFile to the server. In most cases, this flag won't matter, but if you have a driver which works only with OutputFD (such as hpijs 1.0.2), or if you're using the ``-sOutputFile="|cmd"`` syntax, you'll need to set it. + +``-dBitsPerSample=N`` + This parameter controls the number of bits per sample. The default value of 8 should be appropriate for most work. For monochrome images, use ``-dBitsPerSample=1``. + + +Generic Ghostscript options that are particularly relevant for IJS are summarized below: + +``-rnumber -rnumber1xnumber2`` + Sets the resolution, in dpi. If the resolution is not specified, Ghostscript queries the IJS server to determine the preferred resolution. When the resolution is specified, it overrides the value (if any) preferred by the IJS server. + +``-dDuplex -dTumble`` + These flags enable duplex (two-sided) printing. ``Tumble`` controls the orientation. When ``Tumble`` is false, the pages are oriented suitably at the left or right. When ``Tumble`` is true, the pages are oriented suitably for binding at the top or bottom. + +``-sProcessColorModel={name}`` + Use this flag to select the process color model. Suitable values include ``DeviceGray``, ``DeviceRGB``, and ``DeviceCMYK``. + + +Building IJS +~~~~~~~~~~~~~~~~~~~~~ + +IJS is included by default on Unix gcc builds, and also in autoconf'ed builds. Others may need some ``makefile`` tweaking. Firstly, make sure the IJS device is selected: + +``DEVICE_DEVS2=$(DD)ijs.dev`` + Next, make sure that the path and execution type are set in the top level makefile. The values for Unix are as follows: + +``IJSSRCDIR=ijs IJSEXECTYPE=unix`` + At present, "unix" and "win" are the only supported values for ``IJSEXECTYPE``. If neither sounds appropriate for your system, it's possible that more porting work is needed. + +Lastly, make sure that ``ijs.mak`` is included in the top level ``makefile``. It should be present right after the include of ``icclib.mak``. + +IJS is not inherently platform-specific. We're very much interested in taking patches from people who have ported it to non-mainstream platforms. And once it's built, you won't have to recompile Ghostscript to support new drivers! + + + +Rinkj - Resplendent inkjet driver +--------------------------------------------------- + +The Rinkj driver is an experimental new driver, capable of driving some Epson printers at a very high level of quality. It is not currently recommended for the faint of heart. + +You will need to add the following line to your ``makefile``: + +``DEVICE_DEVS2=$(DD)rinkj.dev`` + Most of the configuration parameters, including resolution, choice of printer model, and linearization curves, are in a separate setup file. In addition, we rely heavily on an ICC profile for mapping document colors to actual device colors. + +A typical command line invocation is: + +.. code-block:: bash + + gs -r1440x720 -sDEVICE=rinkj -sOutputFile=/dev/usb/lp0 -sSetupFile=lib/rinkj-2200-setup -sProfileOut=2200-cmyk.icm -dNOPAUSE -dBATCH file.ps + +Individual Rinkj command line parameters are as follows: + +``-sSetupFile={path}`` + Specifies the path for the setup file. + +``-sProfileOut={path}`` + Specifies the path for the output ICC profile. This profile should be a link profile, mapping the ``ProcessColorModel`` (``DeviceCMYK`` by default) to the device color space. + +For 6- and 7-color devices, the target color space for the output profile is currently a 4-component space. The conversion from this into the 6- or 7-color space (the "ink split") is done by lookup tables in the setup file. + + +Setup files are in a simple "Key: value" text format. Relevant keys are: + +``Manufacturer:{name} Model:{name}`` + The manufacturer and model of the individual device, using the same syntax as IEEE printer identification strings. Currently, the only supported manufacturer string is "EPSON", and the only supported model strings are "Stylus Photo 2200" and "Stylus Photo 7600". + +``Resolution:{x-dpi}x{y-dpi}`` + The resolution in dpi. Usually, this should match the Ghostscript resolution set with the ``-r`` switch. Otherwise, the page image will be scaled. + +``Dither:{int}`` + Selects among variant dither options. Currently, the choices are 1 for one-bit dither, and 2, for a 2-bit variable dot dither. + +``Aspect:{int}`` + Controls the aspect ratio for highlight dot placement. Valid values are 1, 2, and 4. For best results, choose a value near the x resolution divided by the y resolution. For example, if resolution is 1440x720, aspect should be 2. + +``Microdot:{int}`` + Chooses a microdot size. On EPSON devices, this value is passed directly through to the "ESC ( e" command. See EPSON documentation for further details (see, I told you this wasn't for the faint of heart). + +``Unidirectional:{int}`` + Enables (1) or disables (0) unidirectional printing, which is slower but possibly higher quality. + +``AddLut:{plane}`` + Adds a linearization look-up table. The plane is one of "CcMmYKk". The lookup table data follows. The line immediately following AddLut is the number of data points. Then, for each data point is a line consisting of two space-separated floats - the output value and the input value. If more than one LUT is specified for a single plane, they are applied in sequence. + +A typical setup file is supplied in ``lib/rinkj-2200-setup``. It is configured for the 2200, but can be adapted to the 7600 just by changing the "Model" line. + +A known issue with this driver is poor support for margins and page size. In some cases, this will cause an additional page to be ejected at the end of a job. You may be able to work around this by supplying a cut-down value for ``-dDEVICEHEIGHTPOINTS``, for example 755 for an 8.5x11 inch page on the EPSON 2200. + + + +HP Deskjet official drivers +----------------------------------- + +HP provides official drivers for many of their Deskjet printer models. In order to use these drivers, you will need the HP Inkjet Server as well as Ghostscript, available from `HP Linux Imaging and Printing`_. This version of Ghostscript includes the patch from version 0.97 of the ``hpijs`` software. If you are installing ``hpijs`` from an RPM, you will only need the hpijs RPM, not the Ghostscript-hpijs one, as the code needed to work with ``hpijs`` is already included. + +Note that newer version of the ``hpijs`` drivers support the IJS protocol. If you can, you should consider using the :title:`ijs` driver instead. Among other things, the ``hpijs`` Ghostscript driver is Unix-only, and is untested on older Unix platforms. + +As of the 0.97 version, ``hpijs`` supports the following printer models: + +**e-Series**: e-20 + +**DeskJet 350C Series**: 350C + +**DeskJet 600C Series**: 600C, 660C, 670/672C, 670TV, 680/682C + +**DeskJet 600C Series Photo**: 610/612C, 640/648C, 690/692/693/694/695/697C + +**DeskJet 630C Series**: 630/632C + +**DeskJet 800C Series**: 810/812C, 830/832C, 840/842/843C, 880/882C, 895C + +**DeskJet 900C Series, PhotoSmart**: 930/932C, 950/952C, 970C, PhotoSmart 1000/1100 + +**DeskJet 990C, PhotoSmart**: 960C, 980C, 990C, PhotoSmart 1215/1218 + + +You will need to add the following line to your ``makefile``: + +.. code-block:: bash + + DEVICE_DEVS2=$(DD)DJ630.dev $(DD)DJ6xx.dev $(DD)DJ6xxP.dev $(DD)DJ8xx.dev $(DD)DJ9xx.dev $(DD)DJ9xxVIP.dev $(DD)AP21xx.dev + + +Please see `HP Linux Imaging and Printing`_ for more information about this driver. Thanks to the folks at HP, especially David Suffield for making this driver available and working to integrate it with Ghostscript. + + +Gimp-Print driver collection +----------------------------------- + +The Gimp-Print project provides a large collection of printer drivers with an IJS interface. Please see `Gimp print`_ for details. + + + + +MS Windows printers +----------------------------------- + +This section was written by Russell Lang, the author of Ghostscript's MS Windows-specific printer driver, and updated by Pierre Arnaud. + +The :title:`mswinpr2` device uses MS Windows printer drivers, and thus should work with any printer with device-independent bitmap (DIB) raster capabilities. The printer resolution cannot be selected directly using PostScript commands from Ghostscript: use the printer setup in the Control Panel instead. It is however possible to specify a maximum resolution for the printed document (see below). + +If no Windows printer name is specified in ``-sOutputFile``, Ghostscript prompts for a Windows printer using the standard Print Setup dialog box. You must set the orientation to Portrait and the page size to that expected by Ghostscript; otherwise the image will be clipped. Ghostscript sets the physical device size to that of the Windows printer driver, but it does not update the PostScript clipping path. + +If a Windows printer name is specified in ``-sOutputFile`` using the format "``%printer%printer_name``", for instance: + +.. code-block:: bash + + gs ... -sOutputFile="%printer%Apple LaserWriter II NT" + + +Then Ghostscript attempts to open the Windows printer without prompting (except, of course, if the printer is connected to FILE:). Ghostscript attempts to set the Windows printer page size and orientation to match that expected by Ghostscript, but doesn't always succeed. It uses this algorithm: + +#. If the requested page size matches one of the Windows standard page sizes +/- 2mm, request that standard size. +#. Otherwise if the requested page size matches one of the Windows standard page sizes in landscape mode, ask for that standard size in landscape. +#. Otherwise ask for the page size by specifying only its dimensions. +#. Merge the requests above with the defaults. If the printer driver ignores the requested paper size, no error is generated: it will print on the wrong paper size. +#. Open the Windows printer with the merged orientation and size. + + +The Ghostscript physical device size is updated to match the Windows printer physical device. + + + +Supported command-line parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :title:`mswinpr2` device supports a limited number of command-line parameters (e.g. it does not support setting the printer resolution). The recognized parameters are the following: + + +``-sDEVICE=mswinpr2`` + Selects the MS Windows printer device. If Ghostscript was not compiled with this device as the default output device, you have to specify it on the command line. + +``-dNoCancel`` + Hides the progress dialog, which shows the percent of the document page already processed and also provides a cancel button. This option is useful if GS is intended to print pages in the background, without any user intervention. + +``-sOutputFile="%printer%printer_name"`` + Specifies which printer should be used. The ``printer_name`` should be typed exactly as it appears in the Printers control panel, including spaces. + +Supported options (device properties) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Several extra options exist which cannot be set through the command-line, but only by executing the appropriate PostScript setup code. These options can be set through the inclusion of a setup file on the command-line: + +.. code-block:: bash + + gs ... setup.ps ... + +The ``setup.ps`` file is responsible for the device selection, therefore you should not specify the ``-sDEVICE=mswinpr2`` option on the command-line if you are using such a setup file. Here is an example of such a setup file: + +.. code-block:: postscript + + mark + /NoCancel true % don't show the cancel dialog + /BitsPerPixel 4 % force 4 bits/pixel + /UserSettings + << + /DocumentName (Ghostscript document) % name for the Windows spooler + /MaxResolution 360 % maximum document resolution + >> + (mswinpr2) finddevice % select the Windows device driver + putdeviceprops + setdevice + + +This example disables the progress dialog (same as the ``-dNoCancel`` option), forces a 4 bits/pixel output resolution and specifies additional user settings, such as the document name (which will be displayed by the Windows spooler for the queued document) and the maximum resolution (here 360 dpi). It then finds and selects an instance of the MS Windows device printer and activates it. This will show the standard printer dialog, since no ``/OutputFile`` property was specified. + +The following options are available: + + +``/NoCancel boolean`` + Disables (hides) the progress dialog when set to true or show the progress dialog if not set or set to false. + +``/OutputFile string`` + Specifies which printer should be used. The string should be of the form ``%printer%printer_name``, where the ``printer_name`` should be typed exactly as it appears in the Printers control panel, including spaces. + +``/QueryUser integer`` + Shows the standard printer dialog (1 or any other value), shows the printer setup dialog (2) or selects the default Windows printer without any user interaction (3). + +``/BitsPerPixel integer`` + Sets the device depth to the specified bits per pixel. Currently supported values are 1 (monochrome), 4 (CMYK with screening handled by Ghostscript) and 24 (True Color, dithering handled by the Windows printer driver; this option can produce huge print jobs). + +``/UserSettings dict`` + Sets additional options, defined in a dictionary. The following properties can be set: + + ``/DocumentName string`` + Defines the user friendly document name which will be displayed by the Windows spooler. + + ``/DocumentRange [n1 n2]`` + Defines the range of pages contained in the document. This information can be used by the printer dialog, in conjunction with the following property. + + ``/SelectedRange [n1 n2]`` + Defines the selected range of pages. This information will be displayed in the printer dialog and will be updated after the user interaction. A PostScript program could check these values and print only the selected page range. + + ``/MaxResolution dpi`` + Specifies the maximum tolerated output resolution. If the selected printer has a higher resolution than dpi, then Ghostscript will render the document with a submultiple of the printer resolution. For example, if ``MaxResolution`` is set to 360 and the output printer supports up to 1200 dpi, then Ghostscript renders the document with an internal resolution of 1200/4=300 dpi. This can be very useful to reduce the memory requirements when printing in True Color on some high resolution ink-jet color printers. + + +These properties can be queried through the `currentpagedevice` operator. The following PostScript code snippet shows how to do it for some of the properties: + +.. code-block:: postscript + + currentpagedevice /BitsPerPixel get == % displays the selected depth + + currentpagedevice /UserSettings get % get the additional options.. + /us exch def % ..and assign them to a variable + + us /DocumentName get == % displays the document name + us /SelectedRange get == % displays the selected page range + + % other misc. information (don't rely on them) + + us /Color get == % 1 => monochrome output, 2 => color output + us /PrintCopies get == % displays the number of copies requested + + +There are a few undocumented parameters stored in the ``UserSettings`` dictionary. You should not rely on them. Their use is still experimental and they could be removed in a future version. + +Duplex printing +~~~~~~~~~~~~~~~~~~~~~ + +If the Windows printer supports the duplex printing feature, then it will also be available through the :title:`mswinpr2` device. You can query for this support through the ``/Duplex`` property of the ``currentpagedevice``. If it returns ``null``, then the feature is not supported by the selected printer. Otherwise, true means that the printer is currently set up to print on both faces of the paper and false that it is not, but that it can. + +The following example shows how to print on both faces of the paper (using the long side of the paper as the reference): + +.. code-block:: postscript + + << /Duplex true /Tumble false >> setpagedevice + + + +Sun SPARCprinter +---------------------------- + +This section was contributed by Martin Schulte. + +With a SPARCprinter you always buy software that enables you to do PostScript printing on it. A page image is composed on the host, which sends a bitmap to the SPARCprinter through a special SBUS video interface. So the need for a Ghostscript interface to the SPARCprinter seems low, but on the other hand, Sun's software prints some PostScript drawings incorrectly: some pages contain a thin vertical line of rubbish, and on some Mathematica drawings the text at the axes isn't rotated. Ghostscript, however, gives the correct results. Moreover, replacing proprietary software should never be a bad idea. + +The problem is that there has yet been no effort to make the SPARCPrinter driver behave like a BSD output filter. I made my tests using the script shown here. + +Installation +~~~~~~~~~~~~~~~~~~~~~ + +Add ``sparc.dev`` to ``DEVICE_DEVS`` and compile Ghostscript as described in the documentation on how to build Ghostscript. Afterwards you can use the following script as an example for printing after modifying it with the right pathnames -- including for ``{GSPATH}`` the full ``pathname`` of the Ghostscript executable: + +.. code-block:: postscript + + outcmd1='/vol/local/lib/troff2/psxlate -r' + outcmd2='{GSPATH} -sDEVICE=sparc -sOUTPUTFILE=/dev/lpvi0 -' + + if [ $# -eq 0 ] + then + $outcmd1 | $outcmd2 + else + cat $* | $outcmd1 | $outcmd2 + fi + + + +Problems +~~~~~~~~~~~~~~~~~~~~~ + +Since ``/dev/lpi`` can be opened only for exclusive use, if another job has it open (``engine_ctl_sparc`` or another Ghostscript are the most likely candidates), Ghostscript stops with "Error: /invalidfileaccess in --.outputpage--" + +In case of common printer problems like being out of paper, a warning describing the reason is printed to stdout. The driver tries access again each five seconds. Due to a problem with the device driver (in the kernel) the reason for printer failure isn't always reported correctly to the program. This is the case, for instance, if you open the top cover (error E5 on the printer's display). Look at the display on the printer itself if a "Printer problem with unknown reason" is reported. Fatal errors cause the print job to be terminated. + + +.. note:: + + There is some confusion whether the resolution setting should be the integers 300 and 400, or the symbolic constants DPI300 and DPI400 (defined in ``lpviio.h``). Ghostscript releases have had it both ways. It is currently the latter. However, INOUE Namihiko reports (in bug #215256) that the former works better for him. If anyone has a definitive answer, please let us know. + + + + +Apple dot matrix printer +------------------------------ + +This section was contributed by `Mark Wedel`_. + +The Apple Dot Matrix Printer (DMP) was a parallel predecessor to the Imagewriter printer. As far as I know, Imagewriter commands are a superset of the Dot Matrix printer's, so the driver should generate output that can be printed on Imagewriters. + +To print images, the driver sets the printer for unidirectional printing and 15 characters per inch (cpi), or 120dpi. It sets the line feed to 1/9 inch. When finished, it sets the printer to bidirectional printing, 1/8-inch line feeds, and 12 cpi. There appears to be no way to reset the printer to initial values. + +This code does not set for 8-bit characters (which is required). It also assumes that carriage return-newline is needed, and not just carriage return. These are all switch settings on the DMP, and I have configured them for 8-bit data and carriage return exclusively. Ensure that the Unix printer daemon handles 8-bit (binary) data properly; in my ``SunOS 4.1.1 printcap`` file the string "``ms=pass8,-opost``" works fine for this. + +Finally, you can search ``devdemp.c`` for "Init" and "Reset" to find the strings that initialize the printer and reset things when finished, and change them to meet your needs. + + + + +Special and Test devices +------------------------------ + +The devices in this section are intended primarily for testing. They may be interesting as code examples, as well. + + +Raw 'bit' devices +~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are a collection of 'bit' devices that don't do any special formatting but output 'raw' binary data for the page images. These are used for benchmarking but can also be useful when you want to directly access the raster data. + +The raw devices are :title:`bit bitrgb bitcmyk`. + + +Bounding box output +~~~~~~~~~~~~~~~~~~~~~~~~~ + +There is a special :title:`bbox` "device" that just prints the bounding box of each page. You select it in the usual way: + +.. code-block:: bash + + gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox + +It prints the output in a format like this: + +.. code-block:: bash + + %%BoundingBox: 14 37 570 719 + %%HiResBoundingBox: 14.3ep08066 37.547999 569.495061 718.319158 + +Currently, it always prints the bounding box on stderr; eventually, it should also recognize ``-sOutputFile=``. + +By default, white objects don't contribute to the bounding box because many files fill the whole page with white before drawing other objects. This can be changed by: + +.. code-block:: bash + + << /WhiteIsOpaque true >> setpagedevice + +Note that this device, like other devices, has a resolution and a (maximum) page size. As for other devices, the product (resolution x page size) is limited to approximately 500K pixels. By default, the resolution is 4000 DPI and the maximum page size is approximately 125", or approximately 9000 default (1/72") user coordinate units. If you need to measure larger pages than this, you must reset both the resolution and the page size in pixels, e.g., + +.. code-block:: bash + + gs -dNOPAUSE -dBATCH -sDEVICE=bbox -r100 -g500000x500000 + + +.. note:: + + The box returned by the :title:`bbox` device is just sufficient to contain the pixels which would be rendered by Ghostscript at the selected resolution. The language rendering rules can mean this differs by up to two pixels from the 'theoretical' area covered, and the precise area covered by curves and line joins is also, to some extent, related to the resolution. Finally the actual pixel position needs to be converted back to PostScript points, and that can be affected by mathematical precision, which can cause rounding errors. As a result the bounding box returned may differ very slightly from that which was expected. + + +Ink coverage output +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +There are two special :title:`inkcov` devices that print the ink coverage of each page; the :title:`inkcov` device and the :title:`ink_cov` device. They are selected like this: + + +.. code-block:: bash + + gs -dSAFER -dNOPAUSE -dBATCH -o- -sDEVICE=inkcov Y.pdf + gs -dSAFER -dNOPAUSE -dBATCH -o- -sDEVICE=ink_cov Y.pdf + + +These commands also work as expected: + +.. code-block:: bash + + gs -o X_inkcov.txt -sDEVICE=inkcov Y.pdf + gs -o X_inkcov_page%03d.txt -sDEVICE=inkcov Y.pdf + + +The devices print their output in a format like this: + +.. code-block:: postscript + + Page 1 + 0.10022 0.09563 0.10071 0.06259 CMYK OK + Page 2 + 0.06108 0.05000 0.05834 0.04727 CMYK OK + +The difference between the two devices is that the :title:`inkcov` device considers each rendered pixel and whether it marks the C, M, Y or K channels. So the percentages are a measure of how many device pixels contain that ink. The :title:`ink_cov` device gives the more traditional use of ink coverage, it also considers the amount of each colourant at each rendered pixel, so the percentages in this case are what percentage of the ink is used on the page. + +As an example, If we take a page which is covered by a pure 100% cyan fill both devices would give the same result 1.00 0.00 0.00 0.00; each pixel is marked by the cyan ink and each pixel contains 100% cyan. If however we use a 50% cyan fill the inkcov device will still give 1.00 0.00 0.00 0.00 as 100% of the pixels contain cyan. The ink_cov device, however, would give a result of 0.50 0.00 0.00 0.00. + + +Permutation (DeviceN color model) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With no additional parameters, the device named "permute" looks to Ghostscript like a standard CMYK contone device, and outputs a PPM file, using a simple CMYK->RGB transform. This should be the baseline for regression testing. + +With the addition of ``-dPermute=1``, the internal behavior changes somewhat, but in most cases the resulting rendered file should be the same. In this mode, the color model becomes "DeviceN" rather than "DeviceCMYK", the number of components goes to six, and the color model is considered to be the (yellow, cyan, cyan, magenta, 0, black) tuple. This is what's rendered into the memory buffer. Finally, on conversion to RGB for output, the colors are permuted back. + +As such, this code should check that all imaging code paths are 64-bit clean. Additionally, it should find incorrect code that assumes that the color model is one of ``DeviceGray``, ``DeviceRGB``, or ``DeviceCMYK``. + +Currently, the code has the limitation of 8-bit continuous tone rendering only. An enhancement to do halftones is planned as well. Note, however, that when testing permuted halftones for consistency, it is important to permute the planes of the default halftone accordingly, and that any file which sets halftones explicitly will fail a consistency check. + +spotcmyk (DeviceN color model) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :title:`spotcmyk` device was created for debugging and testing of the :title:`devicen` extensions to Ghostscript that were released in version 8.0. There are also another device (:title:`devicen`) in the same source file. It were created for testing however it are not actually useful except as example code. + + +The :title:`spotcmyk` device was also designed to provide example code for a device which supports spot colors. Spot colors need to be specified prior to opening the first page. This can be done via adding the following to the command line: ``-c "<< /SeparationColorNames [ /Name1 /Name2 ] >> setpagedevice" -f``. + +The :title:`spotcmyk` device produces a binary data file (similar to the :title:`bitcmyk` device) for the CMYK data. This data file has the name specified by the "OutputFile" parameter. The device also produces a binary data file (similar to the :title:`bitmono` device) for each spot color plane. These data files have the name specified by the "OutputFile" parameter with "sn" appended to the end (where "n" is the spot color number 0 to 12)". + +After the :title:`spotcmyk` device produces the binary data files, the files are read and PCX format versions of these files are created with ".pcx" appended to the binary source file name. + +If the :title:`spotcmyk` is being used with three spot colors and the "OutputFile" parameter is ``xxx`` then the following files would be created by the device: + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - ``xxx`` + - binary CMYK data + * - ``xxxs0`` + - binary data for first spot color + * - ``xxxs1`` + - binary data for second spot color + * - ``xxxs2`` + - binary data for third spot color + * - ``xxx.pcx`` + - CMYK data in PCX format + * - ``xxxs0.pcx`` + - first spot color in PCX format + * - ``xxxs1.pcx`` + - second spot color in PCX format + * - ``xxxs2.pcx`` + - third spot color in PCX format + + +The :title:`spotcmyk` device has the creation of the binary data files separated from the creation of the PCX files since the source file is intended as example code and many people may not be interested in the PCX format. The PCX format was chosen because it was simple to implement from pre-existing code and viewers are available. The PCX format does have the dis-advantage that most of those viewers are on Windows. + + +.. _Devices_XCF: + +XCF (DeviceN color model) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The XCF file format is the native image format for the GIMP program. This format is currently supported by two devices: :title:`xcfrgb` and :title:`xcfcmyk`. + +We have been warned by the people supporting the GIMP program that they reserve the right to change the XCF format at anytime and thus these devices may become invalid. They are being included in the documentation because we have received some questions about what these devices do. + +The XCF devices were created for testing of the :title:`devicen` extensions to Ghostscript which were released in version 8.0. + +The :title:`xcfrgb` device uses a ``DeviceRGB`` process color model and creates a normal XCF file. + +The :title:`xcfcmyk` device was created as a means of viewing spot colors for those users that do not have access to either Photoshop (see the PSD devices) or a PCX viewer (see the :title:`spotcmyk` device). + +The :title:`xcfcmyk` device starts by using a ``DeviceCMYK`` process color model. The ``DeviceCMYK`` process color model allows the :title:`xcfcmyk` device to also support spot colors. Spot colors need to be specified prior to opening the first page. This can be done via adding the following to the command line: + +.. code-block:: bash + + -c "<< /SeparationColorNames [ /Name1 /Name2 ] >> setpagedevice" -f + +After a page is complete, the :title:`xcfcmyk` converts the CMYK image data into RGB for storing in the XCF output file. The XCF format does not currently support CMYK data directly. The spot color planes are converted into alpha channel planes. This is done because the XCF format does not currently support spot colors. + + + + + + + + + + + +.. External links + +.. _PNG website: http://www.libpng.org/pub/png/pngintro.html +.. _JPEG FAQ: http://www.faqs.org/faqs/jpeg-faq/ +.. _hOCR: https://en.wikipedia.org/wiki/HOCR +.. _HP Linux Imaging and Printing: https://developers.hp.com/hp-linux-imaging-and-printing/ +.. _Gimp print: gimp-print.sourceforge.net +.. _Mark Wedel: master@cats.ucsc.edu + + +.. include:: footer.rst + diff --git a/doc/src/Drivers.rst b/doc/src/Drivers.rst new file mode 100644 index 00000000..3cccffab --- /dev/null +++ b/doc/src/Drivers.rst @@ -0,0 +1,1732 @@ +.. title:: The Interface between Ghostscript and Device Drivers + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Drivers.htm: +.. _Drivers: + + +The Interface between Ghostscript and Device Drivers +======================================================= + + + + + +Adding a driver +---------------------- + +To add a driver to Ghostscript, first pick a name for your device, say "smurf". (Device names must be 1 to 8 characters, begin with a letter, and consist only of letters, digits, and underscores. Case is significant: all current device names are lower case.) Then all you need do is edit ``contrib.mak`` in two places. + +#. The list of devices, in the section headed "Catalog". Add "smurf" to the list. + +#. The section headed "Device drivers". + +Suppose the files containing the "smurf" driver are called "joe" and "fred". Then you should add the following lines: + + +.. code-block:: postscript + + # ------ The SMURF device ------ # + + smurf_=$(GLOBJ)joe.$(OBJ) $(GLOBJ)fred.$(OBJ) + $(DD)smurf.dev: $(smurf_) + $(SETDEV) $(DD)smurf $(smurf_) + + $(GLOBJ)joe.$(OBJ) : $(GLSRC)joe.c + $(GLCC) $(GLO_)joe.$(OBJ) $(C_) $(GLSRC)joe.c + + $(GLOBJ)fred.$(OBJ) : $(GLSRC)fred.c + $(GLCC) $(GLO_)fred.$(OBJ) $(C_) $(GLSRC)fred.c + +and whatever ``joe.c`` and ``fred.c`` depend on. If the "smurf" driver also needs special libraries, for instance a library named "gorf", then the entry should look like this: + +.. code-block:: postscript + + $(DD)smurf.dev : $(smurf_) + $(SETDEV) $(DD)smurf $(smurf_) + $(ADDMOD) $(DD)smurf -lib gorf + + +If, as will usually be the case, your driver is a printer driver (as :ref:`discussed below<Printer drivers>`), the device entry should look like this: + + +.. code-block:: postscript + + $(DD)smurf.dev : $(smurf_) $(GLD)page.dev + $(SETPDEV) $(DD)smurf $(smurf_) + +or: + +.. code-block:: postscript + + $(DD)smurf.dev : $(smurf_) $(GLD)page.dev + $(SETPDEV) $(DD)smurf $(smurf_) + $(ADDMOD) $(DD)smurf -lib gorf + +.. note:: + + The space before the ``:``, and the explicit compilation rules for the ``.c`` files, are required for portability. + + +Keeping things simple +------------------------ + +If you want to add a simple device (specifically, a monochrome printer), you probably don't need to read the rest of this document; just use the code in an existing driver as a guide. The Epson and Canon BubbleJet drivers ``gdevepsn.c`` and ``gdevbj10.c`` are good models for dot-matrix printers, which require presenting the data for many scan lines at once; the DeskJet/LaserJet drivers in ``gdevdjet.c`` are good models for laser printers, which take a single scan line at a time but support data compression. For color printers, there are unfortunately no good models: the two major color inkjet printer drivers, ``gdevcdj.c`` and ``gdevstc.c``, are far too complex to read. + +On the other hand, if you're writing a driver for some more esoteric device, you probably do need at least some of the information in the rest of this document. It might be a good idea for you to read it in conjunction with one of the existing drivers. + +Duplication of code, and sheer volume of code, is a serious maintenance and distribution problem for Ghostscript. If your device is similar to an existing one, try to implement your driver by adding some parameterization to an existing driver rather than by copying code to create an entirely new source module. ``gdevepsn.c`` and ``gdevdjet.c`` are good examples of this approach. + + +Driver structure +------------------------ + +A device is represented by a structure divided into three parts: + +#. Parameters that are present in all devices but may be different for each device or instance. + +#. An ``initialize_device_procs`` procedure. + +#. Device-specific parameters that may be different for each instance. + +A prototype of the parameter structure (including both generic and device-specific parameters) is defined and initialized at compile time, but is copied and filled in when an instance of the device is created. This structure should be declared as const, but for backward compatibility reasons it is not. + +The ``gx_device_common`` macro defines the common structure elements, with the intent that devices define and export a structure along the following lines. Do not fill in the individual generic parameter values in the usual way for C structures: use the macros defined for this purpose in ``gxdevice.h`` or, if applicable, ``gdevprn.h``. + + +.. code-block:: c + + typedef struct smurf_device_s { + gx_device_common; + ... device-specific parameters ... + } smurf_device; + smurf_device gs_smurf_device = { + ... macro for generic parameter values ..., + initialize_device_procs, + ... device-specific parameter values if any ... + }; + +The device structure instance must have the name ``gs_smurf_device``, where "smurf" is the device name used in ``contrib.mak``. ``gx_device_common`` is a macro consisting only of the element definitions. + +The ``initialize_device_procs`` function pointer is called when the device is created. Its sole job is to initialize the entries in the device procedure table. On entry, the device procedure table will be full of NULL pointers. On exit, any NULLs left in the table will be filled in with pointers to the default routines. Therefore, the routine should set any non-default entries itself. + +Devices that are (in object-oriented terms) derived from 'base' classes (for instance a new printer device that derives from the ``prn`` device) can call provided helper functions for setting the standard functions for that base class. + +For example, if the "smurf" device was a printer device, its ``initialize_device_procs`` procedure might look like: + +.. code-block:: c + + static void smurf_initialize_device_procs(gx_device *dev) { + /* We are derived from a prn device, and can print in the background */ + gdev_prn_initialize_bg(dev); + + /* Override functions for our specifics */ + set_dev_proc(dev, map_color_rgb, smurf_map_color_rgb); + set_dev_proc(dev, map_rgb_color, smurf_map_rgb_color); + ... + } + +The initialize procedure function pointer does not live in the in the device procedure table (and as such is statically initialized at compile time). Nonetheless, we refer to this as being a device procedure in the rest of the discussion here. + +Note that the ``initialize_device_procs`` function may be called with a pointer to a ``gx_device`` rather than to the derived device class. This happens frequently when one device wants to obtain the prototype of another to copy device procedures around. Initialization of items in the device other than device procs should therefore be reserved for the ``initialize_device`` device procedure. + +The use of the initialize procedure is new to Ghostscript 9.55. Previous versions used a statically initialized table of device procedures. We changed to a dynamically initialized system to more easily cope with future changes to the device procedures. + +All the device procedures are called with the device as the first argument. Since each device type is actually a different structure type, the device procedures must be declared as taking a ``gx_device *`` as their first argument, and must cast it to ``smurf_device *`` internally. For example, in the code for the "memory" device, the first argument to all routines is called dev, but the routines actually use mdev to refer to elements of the full structure, using the following standard initialization statement at the beginning of each procedure: + +.. code-block:: c + + gx_memory_device *const mdev = (gx_device_memory *)dev; + +(This is a cheap version of "object-oriented" programming: in C++, for example, the cast would be unnecessary, and in fact the procedure table would be constructed by the compiler.) + +Structure definition +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You should consult the definition of struct ``gx_device_s`` in ``gxdevice.h`` for the complete details of the generic device structure. Some of the most important members of this structure for ordinary drivers are: + +.. list-table:: + :widths: 50 50 + + * - ``const char *dname;`` + - The device name + * - ``bool is_open;`` + - True if device has been opened + * - ``gx_device_color_info color_info;`` + - Color information + * - ``int width;`` + - Width in pixels + * - ``int height;`` + - Height in pixels + +The name in the structure (``dname``) should be the same as the name in ``contrib.mak``. + + +For sophisticated developers only +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If for any reason you need to change the definition of the basic device structure, or to add procedures, you must change the following places: + +- This document and the :ref:`news document<News.htm>` (if you want to keep the documentation up to date). + +- The definition of ``gx_device_common`` and the procedures in ``gxdevcli.h``. + +- Possibly, the default forwarding procedures declared in ``gxdevice.h`` and implemented in ``gdevnfwd.c``. + +- The device procedure record completion routines in ``gdevdflt.c``. + +- Possibly, the default device implementation in ``gdevdflt.c``, ``gdevddrw.c``, and ``gxcmap.c``. + +- The bounding box device in ``gdevbbox.c`` (probably just adding NULL procedure entries if the new procedures don't produce output). + +- These devices that must have complete (non-defaulted) procedure vectors: + + - The null device in ``gdevnfwd.c``. + + - The command list "device" in ``gxclist.c``. This is not an actual device; it only defines procedures. + + - The "memory" devices in ``gdevmem.h`` and ``gdevm*.c``. + +- The clip list accumulation "device" in ``gxacpath.c``. + +- The clipping "devices" ``gxclip.c``, ``gxclip2.c``, and ``gxclipm.c``. + +- The pattern accumulation "device" in ``gxpcmap.c``. + +- The hit detection "device" in ``gdevhit.c``. + +- The generic printer device macros in ``gdevprn.h``. + +- The generic printer device code in ``gdevprn.c``. + +- The ``RasterOp`` source device in ``gdevrops.c``. + + +You may also have to change the code for ``gx_default_get_params`` or ``gx_default_put_params`` in ``gsdparam.c``. + +You should not have to change any of the real devices in the standard Ghostscript distribution (listed in ``devs.mak`` and ``contrib.mak``) or any of your own devices, because all of them are supposed to use the macros in ``gxdevice.h`` or ``gdevprn.h`` to define and initialize their state. + + +Coordinates and types +----------------------- + +Coordinate system +~~~~~~~~~~~~~~~~~~ + +Since each driver specifies the initial transformation from user coordinates to device coordinates, the driver can use any coordinate system it wants, as long as a device coordinate will fit in an int. (This is only an issue on DOS systems, where ints are only 16 bits. User coordinates are represented as floats.) Most current drivers use a coordinate system with (0,0) in the upper left corner, with X increasing to the right and Y increasing toward the bottom. However, there is supposed to be nothing in the rest of Ghostscript that assumes this, and indeed some drivers use a coordinate system with (0,0) in the lower left corner. + +Drivers must check (and, if necessary, clip) the coordinate parameters given to them: they should not assume the coordinates will be in bounds. The ``fit_fill`` and ``fit_copy`` macros in ``gxdevice.h`` are very helpful in doing this. + +Color definition +~~~~~~~~~~~~~~~~~~ + +Between the Ghostscript graphics library and the device, colors are represented in three forms. Color components in a color space (Gray, RGB, DeviceN, etc.) represented as frac values. Device colorants are represented as ``gx_color_value`` values. For many procedures, colors are represented in a type called ``gx_color_index``. All three types are described in more detail in `Types`_. + +The ``color_info`` member of the device structure defines the color and gray-scale capabilities of the device. Its type is defined as follows: + + +.. code-block:: c + + /* + * The enlarged color model information structure: Some of the + * information that was implicit in the component number in + * the earlier conventions (component names, polarity, mapping + * functions) are now explicitly provided. + * + * Also included is some information regarding the encoding of + * color information into gx_color_index. Some of this information + * was previously gathered indirectly from the mapping + * functions in the existing code, specifically to speed up the + * halftoned color rendering operator (see + * gx_dc_ht_colored_fill_rectangle in gxcht.c). The information + * is now provided explicitly because such optimizations are + * more critical when the number of color components is large. + * + * Note: no pointers have been added to this structure, so there + * is no requirement for a structure descriptor. + */ + typedef struct gx_device_color_info_s { + + /* + * max_components is the maximum number of components for all + * color models supported by this device. This does not include + * any alpha components. + */ + int max_components; + + /* + * The number of color components. This does not include any + * alpha-channel information, which may be integrated into + * the gx_color_index but is otherwise passed as a separate + * component. + */ + int num_components; + + /* + * Polarity of the components of the color space, either + * additive or subtractive. This is used to interpret transfer + * functions and halftone threshold arrays. Possible values + * are GX_CM_POLARITY_ADDITIVE or GX_CM_POLARITY_SUBTRACTIVE + */ + gx_color_polarity_t polarity; + + /* + * The number of bits of gx_color_index actually used. + * This must be <= sizeof(gx_color_index), which is usually 64. + */ + byte depth; + + /* + * Index of the gray color component, if any. The max_gray and + * dither_gray values apply to this component only; all other + * components use the max_color and dither_color values. + * + * This will be GX_CINFO_COMP_NO_INDEX if there is no gray + * component. + */ + byte gray_index; + + /* + * max_gray and max_color are the number of distinct native + * intensity levels, less 1, for the gray and all other color + * components, respectively. For nearly all current devices + * that support both gray and non-gray components, the two + * parameters have the same value. + * + * dither_grays and dither_colors are the number of intensity + * levels between which halftoning can occur, for the gray and + * all other color components, respectively. This is + * essentially redundant information: in all reasonable cases, + * dither_grays = max_gray + 1 and dither_colors = max_color + 1. + * These parameters are, however, extensively used in the + * current code, and thus have been retained. + * + * Note that the non-gray values may now be relevant even if + * num_components == 1. This simplifies the handling of devices + * with configurable color models which may be set for a single + * non-gray color model. + */ + gx_color_value max_gray; /* # of distinct color levels -1 */ + gx_color_value max_color; + + gx_color_value dither_grays; + gx_color_value dither_colors; + + /* + * Information to control super-sampling of objects to support + * anti-aliasing. + */ + gx_device_anti_alias_info anti_alias; + + /* + * Flag to indicate if gx_color_index for this device may be divided + * into individual fields for each component. This is almost always + * the case for printers, and is the case for most modern displays + * as well. When this is the case, halftoning may be performed + * separately for each component, which greatly simplifies processing + * when the number of color components is large. + * + * If the gx_color_index is separable in this manner, the comp_shift + * array provides the location of the low-order bit for each + * component. This may be filled in by the client, but need not be. + * If it is not provided, it will be calculated based on the values + * in the max_gray and max_color fields as follows: + * + * comp_shift[num_components - 1] = 0, + * comp_shift[i] = comp_shift[i + 1] + * + ( i == gray_index ? ceil(log2(max_gray + 1)) + * : ceil(log2(max_color + 1)) ) + * + * The comp_mask and comp_bits fields should be left empty by the client. + * They will be filled in during initialization using the following + * mechanism: + * + * comp_bits[i] = ( i == gray_index ? ceil(log2(max_gray + 1)) + * : ceil(log2(max_color + 1)) ) + * + * comp_mask[i] = (((gx_color_index)1 << comp_bits[i]) - 1) + * << comp_shift[i] + * + * (For current devices, it is almost always the case that + * max_gray == max_color, if the color model contains both gray and + * non-gray components.) + * + * If separable_and_linear is not set, the data in the other fields + * is unpredictable and should be ignored. + */ + gx_color_enc_sep_lin_t separable_and_linear; + byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS]; + byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS]; + gx_color_index comp_mask[GX_DEVICE_COLOR_MAX_COMPONENTS]; + /* + * Pointer to name for the process color model. + */ + const char * cm_name; + + } gx_device_color_info; + + +.. note :: + + See `Changing color_info data`_ before changing any information in the ``color_info`` structure for a device. + +It is recommended that the values for this structure be defined using one of the standard macros provided for this purpose. This allows for future changes to be made to the structure without changes being required in the actual device code. + +The following macros (in ``gxdevcli.h``) provide convenient shorthands for initializing this structure for ordinary black-and-white or color devices: + + +.. code-block:: c + + #define dci_black_and_white ... + #define dci_color(depth,maxv,dither) ... + + +The ``#define dci_black_and_white`` macro defines a single bit monochrome device (For example: a typical monochrome printer device.) + +The ``#define dci_color(depth,maxv,dither)`` macro can be used to define a 24 bit RGB device or a 4 or 32 bit CMYK device. + +The ``#define dci_extended_alpha_values`` macro (in ``gxdevcli.h``) specifies most of the current fields in the structure. However this macro allows only the default setting for the ``comp_shift``, ``comp_bits``, and ``comp_mask`` fields to be set. Any device which requires a non-default setting for these fields has to correctly these fields during the device open procedure. See `Separable and linear fields`_ and `Changing color_info data`_. + +The idea is that a device has a certain number of gray levels (``max_gray+1``) and a certain number of colors (``max_rgb+1``) that it can produce directly. When Ghostscript wants to render a given color space color value as a device color, it first tests whether the color is a gray level and if so: + + If ``max_gray`` is large (``>= 31``), Ghostscript asks the device to approximate the gray level directly. If the device returns a valid ``gx_color_index``, Ghostscript uses it. Otherwise, Ghostscript assumes that the device can represent ``dither_gray`` distinct gray levels, equally spaced along the diagonal of the color cube, and uses the two nearest ones to the desired color for halftoning. + +If the color is not a gray level: + + If ``max_rgb`` is large (``>= 31``), Ghostscript asks the device to approximate the color directly. If the device returns a valid ``gx_color_index``, Ghostscript uses it. Otherwise, Ghostscript assumes that the device can represent distinct colors, equally spaced throughout the color cube, and uses two of the nearest ones to the desired color for halftoning. + + +Separable and linear fields +"""""""""""""""""""""""""""""" + +The three fields ``comp_shift``, ``comp_bits``, and ``comp_mask`` are only used if the ``separable_and_linear`` field is set to ``GX_CINFO_SEP_LIN``. In this situation a ``gx_color_index`` value must represent a combination created by or'ing bits for each of the devices's output colorants. The ``comp_shift`` array defines the location (shift count) of each colorants bits in the output ``gx_color_index`` value. The ``comp_bits`` array defines the number of bits for each colorant. The ``comp_mask`` array contains a mask which can be used to isolate the bits for each colorant. These fields must be set if the device supports more than four colorants. + +Changing color_info data +"""""""""""""""""""""""""""""" + +For most devices, the information in the device's ``color_info`` structure is defined by the various device definition macros and the data remains constant during the entire existence of the device. In general the Ghostscript graphics assumes that the information is constant. However some devices want to modify the data in this structure. + +The device's ``put_params`` procedure may change ``color_info`` field values. After the data has been modified then the device should be closed (via a call to ``gs_closedevice``). Closing the device will erase the current page so these changes should only be made before anything has been drawn on a page. + +The device's ``open_device`` procedure may change ``color_info`` field values. These changes should be done before any other procedures are called. + +The Ghostscript graphics library uses some of the data in ``color_info`` to set the default procedures for the ``get_color_mapping_procs``, ``get_color_comp_index``, ``encode_color``, and ``decode_color`` procedures. These default procedures are set when the device is originally created. If any changes are made to the ``color_info`` fields then the device's ``open_device`` procedure has responsibility for insuring that the correct procedures are contained in the device structure. (For an example, see the display device open procedure ``display_open`` and its subroutine ``display_set_color_format`` (in ``gdevdsp.c``). + + + +Types +~~~~~~~~~ + + +Here is a brief explanation of the various types that appear as parameters or results of the drivers. + +``frac`` (defined in ``gxfrac.h``) + This is the type used to represent color values for the input to the color model mapping procedures. It is currently defined as a short. It has a range of ``frac_0`` to ``frac_1``. + +``gx_color_value`` (defined in ``gxdevice.h``) + This is the type used to represent RGB or CMYK color values. It is currently equivalent to unsigned short. However, Ghostscript may use less than the full range of the type to represent color values: ``gx_color_value_bits`` is the number of bits actually used, and ``gx_max_color_value`` is the maximum value, equal to ``(2^gx_max_color_value_bits)-1``. + +``gx_device`` (defined in ``gxdevice.h``) + This is the device structure, as explained above. + +``gs_matrix`` (defined in ``gsmatrix.h``) + This is a 2-D homogeneous coordinate transformation matrix, used by many Ghostscript operators. + +``gx_color_index`` (defined in ``gxcindex.h``) + This is meant to be whatever the driver uses to represent a device color. For example, it might be an index in a color map, or it might be R, G, and B values packed into a single integer. The Ghostscript graphics library gets ``gx_color_index`` values from the device's ``encode_color`` and hands them back as arguments to several other procedures. If the ``separable_and_linear`` field in the device's ``color_info`` structure is not set to ``GX_CINFO_SEP_LIN`` then Ghostscript does not do any computations with ``gx_color_index`` values. + + The special value ``gx_no_color_index`` (defined as ``(~(gx_color_index)(0))`` ) means "transparent" for some of the procedures. + + The size of ``gx_color_index`` can be either 32 or 64 bits. The choice depends upon the architecture of the CPU and the compiler. The default type definition is simply: + + .. code-block:: c + + typedef unsigned long gx_color_index; + + + However if ``GX_COLOR_INDEX_TYPE`` is defined, then it is used as the type for ``gx_color_index``. + + .. code-block:: c + + typedef GX_COLOR_INDEX_TYPE gx_color_index; + + The smaller size (32 bits) may produce more efficient or faster executing code. The larger size (64 bits) is needed for representing either more bits per component or more components. An example of the later case is a device that supports 8 bit contone colorants using a ``DeviceCMYK`` process color model with its four colorants and also supports additional spot colorants. + + Currently ``autoconf`` attempts to find a 64 bit type definition for the compiler being used, and if a 64 bit type is found then ``GX_COLOR_INDEX_TYPE`` is set to the type. + + For Microsoft and the MSVC compiler, ``GX_COLOR_INDEX_TYPE`` will be set to unsigned ``_int64`` if ``USE_LARGE_COLOR_INDEX`` is set to 1 either on the make command line or by editing the definition in ``msvc32.mak``. + + +``gs_param_list`` (defined in gsparam.h) + This is a parameter list, which is used to read and set attributes in a device. See the comments in ``gsparam.h``, and the description of the ``get_params`` and ``put_params`` procedures below, for more detail. + +``gx_tile_bitmap`` (defined in ``gxbitmap.h``) + +``gx_strip_bitmap`` (defined in ``gxbitmap.h``) + These structure types represent bitmaps to be used as a tile for filling a region (rectangle). ``gx_tile_bitmap`` is an older, deprecated type lacking shift and ``rep_shift``; ``gx_strip_bitmap`` has superseded it, and should be used in new code. Here is a copy of the relevant part of the file: + +.. code-block:: c + + /* + * Structure for describing stored bitmaps. + * Bitmaps are stored bit-big-endian (i.e., the 2^7 bit of the first + * byte corresponds to x=0), as a sequence of bytes (i.e., you can't + * do word-oriented operations on them if you're on a little-endian + * platform like the Intel 80x86 or VAX). Each scan line must start on + * a (32-bit) word boundary, and hence is padded to a word boundary, + * although this should rarely be of concern, since the raster and width + * are specified individually. The first scan line corresponds to y=0 + * in whatever coordinate system is relevant. + * + * For bitmaps used as halftone tiles, we may replicate the tile in + * X and/or Y, but it is still valuable to know the true tile dimensions + * (i.e., the dimensions prior to replication). Requirements: + * width % rep_width = 0 + * height % rep_height = 0 + * + * For halftones at arbitrary angles, we provide for storing the halftone + * data as a strip that must be shifted in X for different values of Y. + * For an ordinary (non-shifted) halftone that has a repetition width of + * W and a repetition height of H, the pixel at coordinate (X,Y) + * corresponds to halftone pixel (X mod W, Y mod H), ignoring phase; + * for a shifted halftone with shift S, the pixel at (X,Y) corresponds + * to halftone pixel ((X + S * floor(Y/H)) mod W, Y mod H). In other words, + * each Y increment of H shifts the strip left by S pixels. + * + * As for non-shifted tiles, a strip bitmap may include multiple copies + * in X or Y to reduce loop overhead. In this case, we must distinguish: + * - The height of an individual strip, which is the same as + * the height of the bitmap being replicated (rep_height, H); + * - The height of the entire bitmap (size.y). + * Similarly, we must distinguish: + * - The shift per strip (rep_shift, S); + * - The shift for the entire bitmap (shift). + * Note that shift = (rep_shift * size.y / rep_height) mod rep_width, + * so the shift member of the structure is only an accelerator. It is, + * however, an important one, since it indicates whether the overall + * bitmap requires shifting or not. + * + * Note that for shifted tiles, size.y is the size of the stored bitmap + * (1 or more strips), and NOT the height of the actual tile. The latter + * is not stored in the structure at all: it can be computed as H * W / + * gcd(S, W). + * + * If the bitmap consists of a multiple of W / gcd(S, W) copies in Y, the + * effective shift is zero, reducing it to a tile. For simplicity, we + * require that if shift is non-zero, the bitmap height be less than H * W / + * gcd(S, W). I.e., we don't allow strip bitmaps that are large enough to + * include a complete tile but that don't include an integral number of + * tiles. Requirements: + * rep_shift < rep_width + * shift = (rep_shift * (size.y / rep_height)) % rep_width + * + * For the benefit of the planar device, we now have a num_planes field. + * For chunky data this should be set to 1. For planar data, the data pointer + * points to the first plane of data; subsequent planes of data follow + * immediately after this as if there were num_planes * height lines of data. + */ + typedef struct gx_strip_bitmap_s { + byte *data; + int raster; /* bytes per scan line */ + gs_int_point size; /* width, height */ + gx_bitmap_id id; + ushort rep_width, rep_height; /* true size of tile */ + ushort rep_shift; + ushort shift; + int num_planes; + } gx_strip_bitmap; + + +Coding conventions +---------------------------- + +All the driver procedures defined below that return ``int`` results return 0 on success, or an appropriate negative error code in the case of error conditions. The error codes are defined in ``gserrors.h``; they correspond directly to the errors defined in the PostScript language reference manuals. The most common ones for drivers are: + +``gs_error_invalidfileaccess`` + An attempt to open a file failed. + +``gs_error_ioerror`` + An error occurred in reading or writing a file. + +``gs_error_limitcheck`` + An otherwise valid parameter value was too large for the implementation. + +``gs_error_rangecheck`` + A parameter was outside the valid range. + +``gs_error_VMerror`` + An attempt to allocate memory failed. (If this happens, the procedure should release all memory it allocated before it returns.) + +If a driver does return an error, rather than a simple return statement it should use the ``return_error`` macro defined in ``gx.h``, which is automatically included by ``gdevprn.h`` but not by ``gserrors.h``. For example: + +.. code-block:: c + + return_error(gs_error_VMerror); + + +Allocating storage +~~~~~~~~~~~~~~~~~~~~~~~~ + +While most drivers (especially printer drivers) follow a very similar template, there is one important coding convention that is not obvious from reading the code for existing drivers: driver procedures must not use ``malloc`` to allocate any storage that stays around after the procedure returns. Instead, they must use ``gs_malloc`` and ``gs_free``, which have slightly different calling conventions. (The prototypes for these are in ``gsmemory.h``, which is included in ``gx.h``, which is included in ``gdevprn.h``.) This is necessary so that Ghostscript can clean up all allocated memory before exiting, which is essential in environments that provide only single-address-space multi-tasking (some versions of Microsoft Windows). + +.. code-block:: c + + char *gs_malloc(uint num_elements, uint element_size, const char *client_name); + +Like ``calloc``, but unlike ``malloc``, ``gs_malloc`` takes an element count and an element size. For structures, ``num_elements`` is 1 and ``element_size`` is ``sizeof`` the structure; for byte arrays, ``num_elements`` is the number of bytes and ``element_size`` is 1. Unlike ``calloc``, ``gs_malloc`` does not clear the block of storage. + +The ``client_name`` is used for tracing and debugging. It must be a real string, not ``NULL``. Normally it is the name of the procedure in which the call occurs. + +.. code-block:: c + + void gs_free(char *data, uint num_elements, uint element_size, const char *client_name); + + +Unlike ``free``, ``gs_free`` demands that ``num_elements`` and ``element_size`` be supplied. It also requires a client name, like ``gs_malloc``. + + +Driver instance allocation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All driver instances allocated by Ghostscript's standard allocator must point to a "structure descriptor" that tells the garbage collector how to trace pointers in the structure. For drivers registered in the normal way (using the ``makefile`` approach described above), no special care is needed as long as instances are created only by calling the ``gs_copydevice`` procedure defined in ``gsdevice.h``. If you have a need to define devices that are not registered in this way, you must fill in the ``stype`` member in any dynamically allocated instances with a pointer to the same structure descriptor used to allocate the instance. For more information about structure descriptors, see ``gsmemory.h`` and ``gsstruct.h``. + + + + +Printer drivers +--------------------- + +Printer drivers (which include drivers that write some kind of raster file) are especially simple to implement. The printer driver must implement a ``print_page`` or ``print_page_copies`` procedure. There are macros in ``gdevprn.h`` that generate the device structure for such devices, of which the simplest is ``prn_device``; for an example, see ``gdevbj10.c``. If you are writing a printer driver, we suggest you start by reading ``gdevprn.h`` and the subsection on `Color mapping`_ below; you may be able to ignore all the rest of the driver procedures. + +The ``print_page`` procedures are defined as follows: + +.. code-block:: c + + int (*print_page)(gx_device_printer *, FILE *) + int (*print_page_copies)(gx_device_printer *, FILE *, int) + +This procedure must read out the rendered image from the device and write whatever is appropriate to the file. To read back one or more scan lines of the image, the ``print_page`` procedure must call one of several procedures. Traditionally devices have called ``gdev_prn_copy_scan_lines``, ``gdev_prn_get_bits``, or the generic ``get_bits_rectangle`` device entry point. Alternatively devices may now call the new ``process_page`` entrypoint, which can have significant performance advantages in :ref:`multi-threaded<Printer drivers mt>` situations. + +.. code-block:: c + + int gdev_prn_copy_scan_lines(gx_device_printer *pdev, int y, byte *str, uint size) + +For this procedure, ``str`` is where the data should be copied to, and ``size`` is the size of the buffer starting at ``str``. This procedure returns the number of scan lines copied, or ``<0`` for an error. ``str`` need not be aligned. + +.. code-block:: c + + int gdev_prn_get_bits(gx_device_printer *pdev, int y, byte *str, byte **actual_data) + + +This procedure reads out exactly one scan line. If the scan line is available in the correct format already, ``*actual_data`` is set to point to it; otherwise, the scan line is copied to the buffer starting at str, and ``*actual_data`` is set to ``str``. This saves a copying step most of the time. ``str`` need not be aligned; however, if ``*actual_data`` is set to point to an existing scan line, it will be aligned. (See the description of the ``get_bits`` procedure below for more details.) + +In either of these two cases, each row of the image is stored in the form described in the comment under ``gx_tile_bitmap`` above; each pixel takes the number of bits specified as ``color_info.depth`` in the device structure, and holds values returned by the device's ``encode_color`` procedure. + +The ``print_page`` procedure can determine the number of bytes required to hold a scan line by calling: + + +.. code-block:: c + + uint gdev_prn_raster(gx_device_printer *) + + +For a very simple concrete example of this pattern of use, we suggest reading the code in ``bit_print_page`` in ``gdevbit.c``. + +If the device provides ``print_page``, Ghostscript will call ``print_page`` the requisite number of times to print the desired number of copies; if the device provides ``print_page_copies``, Ghostscript will call ``print_page_copies`` once per page, passing it the desired number of copies. + + +.. _Printer drivers mt: + +Printer drivers (Multi-threaded) +---------------------------------------- + +This interface is new, and subject to change without notice. + +Ghostscript has supported multi-threaded rendering (controlled by the ``-dNumRenderingThreads`` command line option) since version 8.64. This uses multiple threads of execution to accelerate the rendering phase of operations, but driver specific operations (such as compression) have not been able to benefit in the same way. + +As from Ghostscript 9.11 onwards, a new device function, ``process_page`` has been introduced to solve this. A printer driver will be called via the ``print_page`` or ``print_page_copies`` entry point as before, but rather than requesting a rectangle of pixels at a time (by calling ``get_bits_rectangle``), the driver can now invite Ghostscript to "process the page" in whatever sized chunks it chooses. + +While the benefits of ``process_page`` come from its use with multiple rendering threads, it will work perfectly well in single threaded mode too. Devices do not need to implement both schemes. + +.. code-block:: c + + int (*process_page)(gx_device *dev, gx_process_page_options_t *options) + +The device should fill out a ``gx_process_page_options_t`` structure and pass the address of this to the ``process_page`` function. The entries within this structure will control exactly how Ghostscript will process the page. For forwards compatibility devices should ensure that any unknown fields/option bits within the structure are initialised to 0. + +.. code-block:: c + + typedef struct gx_process_page_options_s gx_process_page_options_t; + + struct gx_process_page_options_s + { + int (*init_buffer_fn)(void *arg, gx_device *dev, gs_memory_t *memory, int w, int h, void **buffer); + void (*free_buffer_fn)(void *arg, gx_device *dev, gs_memory_t *memory, void *buffer); + int (*process_fn)(void *arg, gx_device *dev, gx_device *bdev, const gs_int_rect *rect, void *buffer); + int (*output_fn)(void *arg, gx_device *dev, void *buffer); + void *arg; + int options; /* A mask of GX_PROCPAGE_... options bits */ + }; + + +Ghostscript is free to process the page in 1 or more sections. The potential benefits of ``process_page`` come when Ghostscript chooses to use more than 1 section (or "band") and shares the job of rendering these bands between a set of rendering threads. The overall scheme of operation is as follows: + +- Ghostscript will call ``init_buffer_fn`` in turn, once for each rendering thread in use. This function should (as far as possible) allocate any buffering that may be required to cope with a band of the given size. + +- For each band rendered, Ghostscript will call process_fn to process the given rectangle of the page into the buffer. To achieve this ``process_fn`` is passed a buffer device that contains the rendered version of that rectangle (with the ``y`` range adjusted to start from 0). ``process_fn`` should call ``get_bits_rectangle`` as usual to extract the rendered area. If the options to this call are set correctly (using ``GB_RETURN_POINTER``) no copying or additional storage will be required. All the calls to ``process_fn`` will be for non-overlapping rectangles that cover the page, hence ``process_fn`` may overwrite the storage used in the returned buffer device as part of the processing. Several calls to ``process_fn`` may take place simultaneously in different threads, and there is no guarantee that they will happen 'in order'. + +- Ghostscript will call output_fn for each band in turn, passing in the processed buffer containing the output of the ``process_fn`` stage. These calls are guaranteed to happen 'in order', and will be interleaved arbitrarily with the ``process_fn`` calls. Once an ``output_fn`` returns, the buffer may instantly be reused for another ``process_fn`` calls. + +- Once the page has been processed, Ghostscript will call ``free_buffer_fn`` for each allocated buffer to allow the device to clean up. + + +At the time of writing the only defined bit in the options word is ``GX_PROCPAGE_BOTTOM_UP`` which signifies that Ghostscript should render bands from the bottom of the page to the top, rather than the default top to bottom. + +The height of the bands used by Ghostscript when rendering the page can either be specified by the device itself (using the ``band_params`` structure), or can be calculated by Ghostscript based upon the space available to it. It can sometimes be much easier/more efficient to code a device if the band height can be relied upon to take only particular values - for instance, a device that downscales its output will prefer the height to be a multiple of the downscale used, or a device that uses DCT based compression may prefer a multiple of 8. + +To accommodate such needs, before Ghostscript sets up its buffers, it will perform a ``gxdso_adjust_bandheight`` call. A device can catch this call to adjust the calculated band height to a value it would prefer. To avoid invalidating the calculated memory bounds this should generally be a 'fine' adjustment, and always downwards. + +A simple example of how to use ``process_page`` may be found as the :title:`fpng` device. Within this device: + +- The ``init_buffer_fn`` allocates a buffer large enough to hold the compressed version of each band. + +- The ``process_fn`` applies the sub/paeth filters to the buffered image, then compresses each band with ``zlib``. + +- The ``output_fn`` simply writes each compressed buffer to the file. + +- The ``free_buffer_fn`` frees the buffers. + +- In addition, the downscaler is called to demonstrate that it is possible to 'chain' ``process_page`` functions. + + +The :title:`fpng` device is broadly equivalent to the :title:`png16m` device, but performs much better when multiple threads are in use. Compression is potentially worse than with :title:`png16m` due to each band being compressed separately. + +While the ``print_page`` entry point is specific to printer devices, the process_page device entry point is not. It will, however, only be useful for devices that involve rendering the page. As such, neither ``-dNumRenderingThreads`` or ``process_page`` will help accelerate devices such as :title:`pdfwrite` or :title:`ps2write`. + + +Driver procedures +------------------------ + +Most of the procedures that a driver may implement are optional. If a device doesn't supply an optional procedure ``WXYZ``, the entry in the procedure structure may be either ``gx_default_WXYZ``, for instance ``gx_default_strip_tile_rectangle``, or ``NULL`` or 0. (The device procedure must also call the ``gx_default_`` procedure if it doesn't implement the function for particular values of the arguments.) Since, by construction, device procedure entries are set to 0 at creation time, ones that are not explicitly initialised will continue to work even if new (optional) members are added. + +Life cycle +~~~~~~~~~~~~~ + +When a device is first created, it will have an empty device procs table. The system will call the device's ``initialize_device_procs`` function pointer to fill out this table. This operation can never fail. + +.. note:: + + This operation is also used for creating temporary 'prototype' devices for copying device procedures from. + + +A device instance begins life in a closed state. In this state, no output operations will occur. Only the following procedures may be called: + +``initialize_device`` + +``open_device`` + +``get_initial_matrix`` + +``get_params`` + +``put_params`` + +``get_hardware_params`` + + +When ``setdevice`` installs a device instance in the graphics state, it checks whether the instance is closed or open. If the instance is closed, ``setdevice`` calls the open routine, and then sets the state to open. + +There is no user-accessible operation to close a device instance. This is not an oversight – it is required in order to enforce the following invariant: + +If a device instance is the current device in any graphics state, it must be open (have ``is_open`` set to true). + +Device instances are only closed when they are about to be freed, which occurs in three situations: + +- When a ``restore`` occurs, if the instance was created since the corresponding save and is in a VM being restored. I.e., if the instance was created in local VM since a ``save``, it will always be closed and freed by the corresponding ``restore``; if it was created in global VM, it will only be closed by the outermost ``restore``, regardless of the ``save`` level at the time the instance was created. + +- By the garbage collector, if the instance is no longer accessible. + +- When Ghostscript exits (terminates). + + +Open, close, sync, copy +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``void (*initialize_device_procs)(gx_device *dev)`` + Called once a new device instance has been created. The function should initialize the device procedure tables. This cannot fail. NOTE: Clients should rarely need to call a device's ``initialize_device_procs`` procedure: this procedure is mostly used by the internal device creation code. The sole exception here is when a device implementation wishes to copy device function pointers from another device; then a blank ``gx_device`` can be created, and ``initialize_device_procs`` can be used to fill out the device procs table so it can be copied from. + +``int (*initialize_device)(gx_device *dev) [OPTIONAL]`` + Called once a new device instance has been created and the device procs table has been initialized. This function should perform the minimum initialization to any internal device state required. If the initial setup fails, this procedure should return an error; the new instance will be freed. + + .. note :: + Clients should never call a device's ``initialize_device`` procedure: this procedure is only intended for use by the internal device creation code. + +``int (*open_device)(gx_device *) [OPTIONAL]`` + Open the device: do any initialization associated with making the device instance valid. This must be done before any output to the device. The default implementation does nothing. + + .. note :: + Clients should never call a device's ``open_device`` procedure directly: they should always call ``gs_opendevice`` instead. + +``void (*get_initial_matrix)(gx_device *, gs_matrix *) [OPTIONAL]`` + Construct the initial transformation matrix mapping user coordinates (nominally 1/72 inch per unit) to device coordinates. The default procedure computes this from width, height, and ``[xy]_pixels_per_inch`` on the assumption that the origin is in the upper left corner, that is: + + .. code-block:: c + + xx = x_pixels_per_inch/72, xy = 0, + yx = 0, yy = -y_pixels_per_inch/72, + tx = 0, ty = height. + +``int (*sync_output)(gx_device *) [OPTIONAL]`` + Synchronize the device. If any output to the device has been buffered, send or write it now. Note that this may be called several times in the process of constructing a page, so printer drivers should not implement this by printing the page. The default implementation does nothing. + +``int (*output_page)(gx_device *, int num_copies, int flush) [OPTIONAL]`` + Output a fully composed page to the device. The ``num_copies`` argument is the number of copies that should be produced for a hardcopy device. (This may be ignored if the driver has some other way to specify the number of copies.) The flush argument is true for ``showpage``, false for ``copypage``. The default definition just calls ``sync_output``. Printer drivers should implement this by printing and ejecting the page. + +``int (*close_device)(gx_device *) [OPTIONAL]`` + Close the device: release any associated resources. After this, output to the device is no longer allowed. The default implementation does nothing. + + .. note :: + Clients should never call a device's ``close_device`` procedure directly: they should always call ``gs_closedevice`` instead. + + +.. _Color mapping: + +Color and alpha mapping +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Note that code in the Ghostscript library may cache the results of calling one or more of the color mapping procedures. If the result returned by any of these procedures would change (other than as a result of a change made by the driver's ``put_params`` procedure), the driver must call ``gx_device_decache_colors(dev)``. + +The ``map_rgb_color``, ``map_color_rgb``, and ``map_cmyk_color`` are obsolete. They have been left in the device procedure list for backward compatibility. See the ``encode_color`` and ``decode_color`` procedures below. To insure that older device drivers are changed to use the new ``encode_color`` and ``decode_color`` procedures, the parameters for the older procedures have been changed to match the new procedures. To minimize changes in devices that have already been written, the ``map_rgb_color`` and ``map_cmyk_color`` routines are used as the default value for the ``encode_color`` routine. The ``map_cmyk_color`` routine is used if the number of components is four. The ``map_rgb_color`` routine is used if the number of components is one or three. This works okay for RGB and CMYK process color model devices. However this does not work properly for gray devices. The ``encode_color`` routine for a gray device is only passed one component. Thus the ``map_rgb_color`` routine must be modified to only use a single input (instead of three). (See the ``encode_color`` and ``decode_color`` routines below.) + +Colors can be specified to the Ghostscript graphics library in a variety of forms. For example, there are a wide variety of color spaces that can be used such as Gray, RGB, CMYK, DeviceN, Separation, Indexed, CIEbasedABC, etc. The graphics library converts the various input color space values into four base color spaces: Gray, RGB, CMYK, and DeviceN. The DeviceN color space allows for specifying values for individual device colorants or spot colors. + +Colors are converted by the device in a two step process. The first step is to convert a color in one of the base color spaces (Gray, RGB, CMYK, or DeviceN) into values for each device colorant. This transformation is done via a set of procedures provided by the device. These procedures are provided by the ``get_color_mapping_procs`` device procedure. + +Between the first and second steps, the graphics library applies transfer functions to the device colorants. Where needed, the output of the results after the transfer functions is used by the graphics library for halftoning. + +In the second step, the device procedure ``encode_color`` is used to convert the transfer function results into a ``gx_color_index`` value. The ``gx_color_index`` values are passed to specify colors to various routines. The choice of the encoding for a ``gx_color_index`` is up to the device. Common choices are indexes into a color palette or several integers packed together into a single value. The manner of this encoding is usually opaque to the graphics library. The only exception to this statement occurs when halftoning 5 or more colorants. In this case the graphics library assumes that if a colorant values is zero then the bits associated with the colorant in the ``gx_color_index`` value are zero. + + +``int get_color_comp_index(const gx_device * dev, const char * pname, int name_size, int src_index) [OPTIONAL]`` + This procedure returns the device colorant number of the given name. The possible return values are -1, 0 to ``GX_DEVICE_COLOR_MAX_COMPONENTS - 1``, or ``GX_DEVICE_COLOR_MAX_COMPONENTS``. A value of -1 indicates that the specified name is not a colorant for the device. A value of 0 to ``GX_DEVICE_COLOR_MAX_COMPONENTS - 1`` indicates the colorant number of the given name. A value of ``GX_DEVICE_COLOR_MAX_COMPONENTS`` indicates that the given name is a valid colorant name for the device but the colorant is not currently being used. This is used for implementing names which are in ``SeparationColorNames`` but not in ``SeparationOrder``. + + The default procedure returns results based upon process color model of DeviceGray, DeviceRGB, or DeviceCMYK selected by ``color_info.num_components``. This procedure must be defined if another process color model is used by the device or spot colors are supported by the device. + +``const gx_cm_color_map_procs * get_color_mapping_procs(const gx_device * dev, const gx_device ** tdev) [OPTIONAL]`` + This procedure returns a list of three procedures, together with the device to pass to them. These procedures are used to translate values in either Gray, RGB, or CMYK color spaces into device colorant values. A separate procedure is not required for the :title:`devicen` and ``Separation`` color spaces since these already represent device colorants. + + In many cases, the device returned in tdev will be the same as ``dev``, but the caller should not rely on this. For cases where we have a chain of devices (perhaps because of a subclass or compositor device having been introduced internally as part of the rendering process), the actual device that needs to do the color mapping may be a child device of the original one. In such cases ``tdev`` will be returned as a different value to ``dev``. + + The default procedure returns a list of procedures based upon ``color_info.num_components``. These procedures are appropriate for DeviceGray, DeviceRGB, or DeviceCMYK process color model devices. A procedure must be defined if another process color model is used by the device or spot colors are to be supported. All these procedures take a ``gx_device`` pointer; these should be called with the value returned in ``tdev`` NOT the initial value of ``dev``. + + +``gx_color_index (*encode_color)(gx_device * dev, gx_color_value * cv) [OPTIONAL]`` + Map a set of device color values into a ``gx_color_index`` value. The range of legal values of the arguments is 0 to ``gx_max_color_value``. The default procedure packs bits into a ``gx_color_index`` value based upon the values in ``color_info.depth`` and ``color_info.num_components``. + Note that the ``encode_color`` procedure must not return ``gx_no_color_index`` (all 1s). + +``int (*decode_color)(gx_device *, gx_color_index color, gx_color_value * CV) [OPTIONAL]`` + This is the inverse of the ``encode_color`` procedure. Map a ``gx_color_index`` value to color values. The default procedure unpacks bits from the ``gx_color_index`` value based upon the values in ``color_info.depth`` and ``color_info.num_components``. + +``typedef enum { go_text, go_graphics } graphic_object_type; int (*get_alpha_bits)(gx_device *dev, graphic_object_type type) [OPTIONAL]`` + This procedure returns the number of bits to use for anti-aliasing. The default implementation simply returns the ``color_info.anti_alias`` member of the driver structure. + +``void (*update_spot_equivalent_colors)(gx_device *, const gs_state *) [OPTIONAL]`` + This routine provides a method for the device to gather an equivalent color for spot colorants. This routine is called when a ``Separation`` or :title:`devicen` color space is installed. See comments at the start of ``gsequivc.c``. + + .. note:: + This procedure is only needed for devices that support spot colorants and also need to have an equivalent color for simulating the appearance of the spot colorants. + + +Pixel-level drawing +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This group of drawing operations specifies data at the pixel level. All drawing operations use device coordinates and device color values. + +``int (*fill_rectangle)(gx_device *, int x, int y, int width, int height, gx_color_index color)`` + Fill a rectangle with a color. The set of pixels filled is ``{(px,py) | x <= px < x + width and y <= py < y + height}``. In other words, the point (x,y) is included in the rectangle, as are (x+w-1,y), (x,y+h-1), and (x+w-1,y+h-1), but not (x+w,y), (x,y+h), or (x+w,y+h). If width <= 0 or height <= 0, ``fill_rectangle`` should return 0 without drawing anything. + + Note that ``fill_rectangle`` is the only non-optional procedure in the driver interface. + +Bitmap imaging +""""""""""""""""""" + +Bitmap (or pixmap) images are stored in memory in a nearly standard way. The first byte corresponds to (0,0) in the image coordinate system: bits (or polybit color values) are packed into it left to right. There may be padding at the end of each scan line: the distance from one scan line to the next is always passed as an explicit argument. + +``int (*copy_mono)(gx_device *, const unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1) [OPTIONAL]`` + Copy a monochrome image (similar to the PostScript image operator). Each scan line is raster bytes wide. Copying begins at (``data_x``,0) and transfers a rectangle of the given width and height to the device at device coordinate (x,y). (If the transfer should start at some non-zero y value in the data, the caller can adjust the data address by the appropriate multiple of the raster.) The copying operation writes device color ``color0`` at each 0-bit, and ``color1`` at each 1-bit: if ``color0`` or ``color1`` is ``gx_no_color_index``, the device pixel is unaffected if the image bit is 0 or 1 respectively. If ``id`` is different from ``gx_no_bitmap_id``, it identifies the bitmap contents unambiguously; a call with the same ``id`` will always have the same data, raster, and data contents. + + This operation, with ``color0 = gx_no_color_index``, is the workhorse for text display in Ghostscript, so implementing it efficiently is very important. + +``int (*strip_tile_rectangle)(gx_device *, const gx_strip_bitmap *tile, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) [OPTIONAL]`` + Tile a rectangle. Tiling consists of doing multiple ``copy_mono`` operations to fill the rectangle with copies of the tile. The tiles are aligned with the device coordinate system, to avoid "seams". Specifically, the (``phase_x``, ``phase_y``) point of the tile is aligned with the origin of the device coordinate system. (Note that this is backwards from the PostScript definition of halftone phase.) ``phase_x`` and ``phase_y`` are guaranteed to be in the range ``[0..tile->width]`` and ``[0..tile->height]`` respectively. + + If ``color0`` and ``color1`` are both ``gx_no_color_index``, then the tile is a color pixmap, not a bitmap: see the next section. + + This operation is the workhorse for halftone filling in Ghostscript, so implementing it efficiently for solid tiles (that is, where either ``color0`` and ``color1`` are both ``gx_no_color_index``, for colored halftones, or neither one is ``gx_no_color_index``, for monochrome halftones) is very important. + + +Pixmap imaging +""""""""""""""""""" + +Pixmaps are just like bitmaps, except that each pixel may occupy more than one bit. In "chunky" or "Z format", all the bits for each pixel are grouped together. For ``copy_color``, the number of bits per pixel is given by the ``color_info.depth`` parameter in the device structure. The legal values are 1, 2, 4, 8, 16, 24, 32, 40, 48, 56, or 64. The pixel values are device color codes (that is, whatever it is that ``encode_color`` returns). + +If the data is planar, then each plane is contiguous, and the number of planes is given by ``color_info.num_components``. The bits per component is ``depth/num_components``. + +``int (*copy_color)(gx_device *, const unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height) [OPTIONAL]`` + Copy a color image with multiple bits per pixel. The ``raster`` is in bytes, but ``x`` and ``width`` are in pixels, not bits. If ``id`` is different from ``gx_no_bitmap_id``, it identifies the bitmap contents unambiguously; a call with the same ``id`` will always have the same data, raster, and data contents. + +``int (*copy_planes)(gx_device *, const unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, int plane_height) [OPTIONAL]`` + Copy an image with data stored in planar format. The raster is in bytes, but ``x`` and ``width`` are in pixels, not bits. If ``id`` is different from ``gx_no_bitmap_id``, it identifies the bitmap contents unambiguously; a call with the same ``id`` will always have the same data, raster, and data contents. + + Each plane is ``depth/num_components`` number of bits and the distance between planes is ``plane_height`` number of rows. The height is always less than or equal to the ``plane_height``. + +We do not provide a separate procedure for tiling with a pixmap; instead, ``strip_tile_rectangle`` can also take colored tiles. This is indicated by the ``color0`` and ``color1`` arguments' both being ``gx_no_color_index``. In this case, as for ``copy_color``, the raster and height in the "bitmap" are interpreted as for real bitmaps, but the ``x`` and ``width`` are in pixels, not bits. + + +.. code-block:: c + + typedef enum { + transform_pixel_region_begin = 0, + transform_pixel_region_data_needed = 1, + transform_pixel_region_process_data = 2, + transform_pixel_region_end = 3 + } transform_pixel_region_reason; + typedef struct { + void *state; + union { + struct { + const gs_int_rect *clip; + int w; /* source width */ + int h; /* source height */ + int spp; + const gx_dda_fixed_point *pixels; /* DDA to enumerate the destination positions of pixels across a row */ + const gx_dda_fixed_point *rows; /* DDA to enumerate the starting position of each row */ + gs_logical_operation_t lop; + } init; + struct { + const unsigned char *buffer[GX_DEVICE_COLOR_MAX_COMPONENTS]; + int data_x; + gx_cmapper_t *cmapper; + const gs_gstate *pgs; + } process_data; + } u; + } transform_pixel_region_data; + + +``int (*transform_pixel_region)(gx_device *, transform_pixel_reason, transform_pixel_reason_data *data) [OPTIONAL]`` + Transform a 2-dimensional region of pixels into the destination. Given a 2d source block of pixels (supplied as scanline data), this function transforms that data, maps it through the supplied colour lookup function, clips it, and plots it into the device. + + In all calls to this function a negative return value indicates an error. + + Called first with the ``transform_pixel_region_init`` reason code, this prepares for subsequent calls to scale a region as described in the ``data.u.init`` structure. A pointer to any state required for this should be written into ``data.state``, and the caller must pass that in to subsequent calls. + + Subsequently this will be called with ``transform_pixel_region_data_needed``. The function will then check to see if the next scanline of data will be trivially clipped away. If so, then it will return zero to indicate that it is not needed. This can help the caller to avoid unnecessary processing. A positive return value indicates that the line is required. + + For every line where the data is required, the function will be called with ``transform_pixel_region_process_data``. The function will then read and process the line from ``data.u.process_data``. The data in the buffer is packed 8 bit values, which will be fed into the supplied cmapper to set the device color as required. This is then written into the device. + + Once all the scanlines have been fed through calls to ``transform_pixel_region_data_needed`` and ``transform_pixel_region_process_data``, a final call with ``transform_pixel_region_end`` is made that frees the state. + + The default implementation of this device function will generally break the pixel data down into calls to ``fill_rectangle``, though in some cases (notably the portrait 8 bit per component output case), a faster route through ``copy_color`` can be used. + + Memory devices offer a version of this device function that can accelerate direct plotting to the memory array. + + .. note:: + Currently the clipping rectangle is not honoured for skewed (not portrait or landscape) transformations. This is allowed for in the callers. + + +Compositing +"""""""""""""""" + +In addition to direct writing of opaque pixels, devices must also support compositing. Currently two kinds of compositing are defined (``RasterOp`` and alpha-based), but more may be added in the future. + +``int (*copy_alpha)(gx_device *dev, const unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color, int depth) [OPTIONAL]`` + This procedure is somewhat misnamed: it was added to the interface before we really understood alpha channel and compositing. + Fill a given region with a given color modified by an individual alpha value for each pixel. For each pixel, this is equivalent to alpha-compositing with a source pixel whose alpha value is obtained from the pixmap (``data``, ``data_x``, and ``raster``) and whose color is the given color (which has not been premultiplied by the alpha value), using the Sover rule. + + ``depth``, the number of bits per alpha value, is either 2, 4 or 8. Any copy_alpha routine must accept being called with an 8 bit depth. In addition they should accept either 2 or 4 if the corresponding ``get_alpha_bits`` procedure returns either of those values. + +``int (*copy_alpha_hl_color)(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, const gx_drawing_color *pdcolor, int depth) [OPTIONAL]`` + Equivalent function to ``copy_alpha``, using high level color rather than a ``gx_color_index``. + +``int (*composite)(dev_t *dev, gx_device_t **pcdev, const gs_composite_t *pcte, const gs_imager_state *pis, gs_memory_t *memory) [OPTIONAL]`` + Requests that a device perform a compositing operation; the device should composite data written to it with the device's existing data, according to the compositing function defined by ``*pcte``. If a device cannot perform such an operation itself, it will create a compositor device to wrap itself that will perform such operations for it. Accordingly, the caller must watch the return values from this function to understand if a new device has been created to which future calls should be made. + + Devices will normally implement this in one of the following standard ways: + + - Devices that don't do any imaging and don't forward any imaging operations (for example, the null device, the hit detection device, and the clipping list accumulation device) simply set ``*pcdev`` to themselves, and return 0, which effectively ignores the compositing function. + + - "Leaf" devices that do imaging and have no special optimizations for compositing (for example, some memory devices) ask the ``gs_composite_t`` to create a default compositor device that 'wraps' the current device. They put this in ``*pcdev`` and return 1. + + - Leaf devices that can implement some kinds of compositing operation efficiently (for example, monobit memory devices and ``RasterOp``) inspect the type and values of ``*pcte`` to determine whether it specifies such an operation: if so, they create a specialized compositor, and if not, they ask the ``gs_composite_t`` to create a default compositor. They place this in ``*pcdev`` and return 1. + + In short, on every non-error return, ``*pcdev`` will be set either to the leaf device (in the case where no special compositing is required), or to the device that does the compositing. If the return code is 1, then ``*pcdev`` is a new device that was created to wrap dev to perform the compositing for it. Callers may need to spot this case so as to update which device future operations are sent to. + + For forwarding devices, for example, if the call returns 1, then they should update their target device to be the new device. For the graphics library, if the call returns 1, then it should update the current device to be the new one. + + Other kinds of forwarding devices, which don't fall into any of these categories, require special treatment. In principle, what they do is ask their target to create a compositor, and then create and return a copy of themselves with the target's new compositor as the target of the copy. There is a possible default implementation of this approach: if the original device was D with target T, and T creates a compositor C, then the default implementation creates a device F that for each operation temporarily changes D's target to C, forwards the operation to D, and then changes D's target back to T. However, the Ghostscript library currently only creates a compositor with an imaging forwarding device as target in a few specialized situations (banding, and bounding box computation), and these are handled as special cases. + + Note that the compositor may have a different color space, color representation, or bit depth from the device to which it is compositing. For example, alpha-compositing devices use standard-format chunky color even if the underlying device doesn't. + + Closing a compositor frees all of its storage, including the compositor itself. However, since the composite call may return the same device, clients must check for this case, and only call the close procedure if a separate device was created. + + +Polygon-level drawing +~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the pixel-level drawing operations that take integer device coordinates and pure device colors, the driver interface includes higher-level operations that draw polygons using fixed-point coordinates, possibly halftoned colors, and possibly a non-default logical operation. + +The ``fill_*`` drawing operations all use the center-of-pixel rule: a pixel is colored if, and only if, its center falls within the polygonal region being filled. If a pixel center (X+0.5,Y+0.5) falls exactly on the boundary, the pixel is filled if, and only if, the boundary is horizontal and the filled region is above it, or the boundary is not horizontal and the filled region is to the right of it. + +``int (*fill_trapezoid)(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, fixed ybot, fixed ytop, bool swap_axes, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) [OPTIONAL]`` + Fill a trapezoid. The bottom and top edges are parallel to the x axis, and are defined by ``ybot`` and ``ytop``, respectively. The left and right edges are defined by ``left`` and ``right``. Both of these represent lines (``gs_fixed_edge`` is defined in ``gxdevcli.h`` and consists of ``gs_fixed_point`` start and end points). The y coordinates of these lines need not have any specific relation to ``ybot`` and ``ytop``. The routine is defined this way so that the filling algorithm can subdivide edges and still guarantee that the exact same pixels will be filled. If ``swap_axes`` is set, the meanings of X and Y are interchanged. + +``int (*fill_parallelogram)(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) [OPTIONAL]`` + Fill a parallelogram whose corners are (``px``,``py``), (``px+ax``,``py+ay``), (``px+bx``,``py+by``), and (``px+ax+bx``,``py+ay+by``). There are no constraints on the values of any of the parameters, so the parallelogram may have any orientation relative to the coordinate axes. + +``int (*fill_triangle)(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) [OPTIONAL]`` + Fill a triangle whose corners are (``px``,``py``), (``px+ax``,``py+ay``), and (``px+bx``,``py+by``). + +``int (*draw_thin_line)(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, const gx_drawing_color *pdcolor, gs_logical_operation_t lop) [OPTIONAL]`` + Draw a one-pixel-wide line from (``fx0``,``fy0``) to (``fx1``,``fy1``). + + +Linear color drawing +~~~~~~~~~~~~~~~~~~~~~~~~ + +Linear color functions allow fast high quality rendering of shadings on continuous tone devices. They implement filling simple areas with a lineary varying color. These functions are not called if the device applies halftones, or uses a non-separable or a non-linear color model. + +``int (*fill_linear_color_triangle) (dev_t *dev, const gs_fill_attributes *fa, const gs_fixed_point *p0, const gs_fixed_point *p1, const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) [OPTIONAL]`` + This function is the highest level one within the linear color function group. It fills a triangle with a linearly varying color. Arguments specify 3 points in the device space - vertices of a triangle, and their colors. The colors are represented as vectors of positive fractional numbers, each of which represents a color component value in the interval [0,1]. The number of components in a vector in the number of color components in the device (process) color model. + + The implementation fills entire triangle. The filling rule is same as for Polygon-level drawing. The color of each pixel within the triangle is computed as a linear interpolation of vertex colors. + + The implementation may reject the request if the area or the color appears too complex for filling in a single action. For doing that the implementation returns 0 and must not paint any pixel. In this case the graphics library will perform a subdivision of the area into smaller triangles and call the function again with smaller areas. + + .. important:: + + - Do not try to decompose the area within the implementation of ``fill_linear_color_triangle``, because it can break the plane coverage contiguity and cause a dropout. Instead request that the graphics library should perform the decomposition. The graphics library is smart enough to do that properly. + + - The implementation must handle a special case, when only 2 colors are specified. It happens if ``p2`` is ``NULL``. This means that the color does not depend on the X coordinate, i.e. it forms a linear gradient along the Y axis. The implementation must not reject (return 0) such cases. + + - The device color component value 1 may be represented with several hexadecimal values : ``0x7FFF0000``, ``0x7FFFF000``, ``0x7FFFFF00``, etc., because the precision here exceeds the color precision of the device. To convert a ``frac31`` value into a device color component value, first drop (ignore) the sign bit, then drop least significant bits - so many ones as you need to fit the device color precision. + + - The ``fa`` argument may contain the ``swap_axes`` bit set. In this case the implementation must swap (transpose) X and Y axes. + + - The implementation must not paint outside the clipping rectangle specified in the ``fa`` argument. If ``fa->swap_axes`` is true, the clipping rectangle is transposed. + + See ``gx_default_fill_linear_color_triangle`` in ``gdevddrw.c`` for sample code. + +``int (*fill_linear_color_trapezoid) (dev_t *dev, const gs_fill_attributes *fa, const gs_fixed_point *p0, const gs_fixed_point *p1, const gs_fixed_point *p2, const gs_fixed_point *p3, const frac31 *c0, const frac31 *c1, const frac31 *c2, const frac31 *c2) [OPTIONAL]`` + This function is a lower level one within the linear color function group. The default implementation of ``fill_linear_color_triangle`` calls this function 1-2 times per triangle. Besides that, this function may be called by the graphics library for other special cases, when a decomposition into triangles appears undesirable. + + While the prototype can specify a bilinear color, we assume that the implementation handles linear colors only. This means that the implementation can ignore any of ``c0``, ``c1``, ``c2``, ``c3`` . The graphics library takes a special care of the color linearity when calling this function. The reason for passing all 4 color arguments is to avoid color precision problems. + + Similarly to ``fill_linear_color_triangle`` , this function may be called with only 2 colors, and may reject areas as being too complex. All those important notes are applicable here. + + Sample code may be found in in ``gxdtfill.h``; be aware it's rather complicated. A linear color function is generated from it as ``gx_fill_trapezoid_ns_lc`` with the following template parameters: + + .. code-block:: c + + #define LINEAR_COLOR 1 + #define EDGE_TYPE gs_linear_color_edge + #define FILL_ATTRS const gs_fill_attributes * + #define CONTIGUOUS_FILL 0 + #define SWAP_AXES 0 + #define FILL_DIRECT 1 + + See the helplers ``init_gradient``, ``step_gradient`` (defined in ``gdevddrw.c``), how to manage colors. + + See ``check_gradient_overflow`` (defined in in ``gdevddrw.c``), as an example of an area that can't be painted in a single action due to 64-bits fixed overflows. + + +``int (*fill_linear_color_scanline) (dev_t *dev, const gs_fill_attributes *fa, int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, int32_t cg_den) [OPTIONAL]`` + This function is the lowest level one within the linear color function group. It implements filling a scanline with a linearly varying color. The default implementation for ``fill_linear_color_trapezoid`` calls this function, and there are no other calls to it from the graphics libary. Thus if the device implements ``fill_linear_color_triangle`` and ``fill_linear_color_trapezoid`` by own means, this function may be left unimplemented. + + ``i`` and ``j`` specify device coordinates (indices) of the starting pixel of the scanline, ``w`` specifies the width of the scanline, i.e. the number of pixels to be painted to the right from the starting pixel, including the starting pixel. + + ``c0`` specifies the color for the starting pixel as a vector of fraction values, each of which represents a color value in the interval [0,1]. + + ``c0_f`` specify a fraction part of the color for the starting pixel. See the formula below about using it. + + ``cg_num`` specify a numerator for the color gradient - a vector of values in [-1,1], each of which correspond to a color component. + + ``cg_den`` specify the denominator for the color gradient - a value in [-1,1]. + + The color for the pixel ``[i + k, j]`` to be computed like this : + + ``(double)(c0[n] + (c0_f[n] + cg_num[n] * k) / cg_den) / (1 ^ 31 - 1)`` + + where ``0 <= k <= w`` , and ``n`` is a device color component index. + + .. important:: + + - The ``fa`` argument may contain the ``swap_axes`` bit set. In this case the implementation must swap (transpose) X and Y axes. + + - The implementation must not paint outside the clipping rectangle specified in the ``fa`` argument. If ``fa->swap_axes`` is true, the clipping rectangle is transposed. + + See ``gx_default_fill_linear_color_scanline`` in ``gdevdsha.c`` for sample code. + + + +High-level drawing +~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the lower-level drawing operations described above, the driver interface provides a set of high-level operations. Normally these will have their default implementation, which converts the high-level operation to the low-level ones just described; however, drivers that generate high-level (vector) output formats such as :title:`pdfwrite`, or communicate with devices that have firmware for higher-level operations such as polygon fills, may implement these high-level operations directly. For more details, please consult the source code, specifically: + + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Header + - Defines + * - gxpaint.h + - ``gx_fill_params``, ``gx_stroke_params`` + * - gxfixed.h + - fixed, ``gs_fixed_point`` (used by ``gx_*_params``) + * - gxgstate.h + - ``gs_imager_state`` (used by ``gx_*_params``) + * - gxline.h + - ``gx_line_params`` (used by ``gs_imager_state``) + * - gslparam.h + - line cap/join values (used by ``gx_line_params``) + * - gxmatrix.h + - ``gs_matrix_fixed`` (used by ``gs_imager_state``) + * - gspath.h, gxpath.h, gzpath.h + - ``gx_path`` + * - gxcpath.h, gzcpath.h + - ``gx_clip_path`` + + +For a minimal example of how to implement the high-level drawing operations, see ``gdevtrac.c``. + +Paths +""""""""""" + +``int (*fill_path)(gx_device *dev, const gs_imager_state *pis, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) [OPTIONAL]`` + Fill the given path, clipped by the given clip path, according to the given parameters, with the given color. The clip path pointer may be ``NULL``, meaning do not clip. + + The implementation must paint the path with the specified device color, which may be either a pure color, or a pattern. If the device can't handle non-pure colors, it should check the color type and call the default implementation ``gx_default_fill_path`` for cases which it can't handle. The default implementation will perform a subdivision of the area to be painted, and will call other device virtual functions (such as ``fill_linear_color_triangle``) with simpler areas. + +``int (*stroke_path)(gx_device *dev, const gs_imager_state *pis, gx_path *ppath, const gx_stroke_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) [OPTIONAL]`` + Stroke the given path, clipped by the given clip path, according to the given parameters, with the given color. The clip path pointer may be ``NULL``, meaning not to clip. + +``int (*fill_mask)(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, const gx_drawing_color *pdcolor, int depth, int command, const gx_clip_path *pcpath) [OPTIONAL]`` + Color the 1-bits in the given mask (or according to the alpha values, if depth > 1), clipped by the given clip path, with the given color and logical operation. The clip path pointer may be ``NULL``, meaning do not clip. The parameters ``data``, ``...``, ``height`` are as for ``copy_mono``; ``depth`` is as for ``copy_alpha``; ``command`` is as below. + +The function specification f +"""""""""""""""""""""""""""""""""""" + +"Command" indicates the raster operation and transparency as follows: + + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - Bits + - Notes + * - 7-0 + - raster op + * - 8 + - 0 if source opaque, 1 if source transparent + * - 9 + - 0 if texture opaque, 1 if texture transparent + * - 10 + - 1 if pdf transparency is in use, 0 otherwise. + + This makes no difference to the rendering, + + but forces the raster operation to be considered non-idempotent by internal routines. + * - 11 + - 1 if the target of this operation is a specific plane, rather than all planes. + + The plane in question is given by bits 13 upwards. This is only used by the planar device. + * - 12- + - If bit 11 = 1, then bits 1 + + +In general most devices should just check to see that bits they do not handle (11 and above typically) are zero, and should jump to the default implementation, or return an error otherwise. + +The raster operation follows the Microsoft and H-P specification. It is an 8-element truth table that specifies the output value for each of the possible 2×2×2 input values as follows: + + + +.. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Bit + - Texture + - Source + - Destination + * - 7 + - 1 + - 1 + - 1 + * - 6 + - 1 + - 1 + - 0 + * - 5 + - 1 + - 0 + - 1 + * - 4 + - 1 + - 0 + - 0 + * - 3 + - 0 + - 1 + - 1 + * - 2 + - 0 + - 1 + - 0 + * - 1 + - 0 + - 0 + - 1 + * - 0 + - 0 + - 0 + - 0 + + +Transparency affects the output in the following way. A source or texture pixel is considered transparent if its value is all 1s (for instance, 1 for bitmaps, ``0xffffff`` for 24-bit RGB pixmaps) and the corresponding transparency bit is set in the command. For each pixel, the result of the Boolean operation is written into the destination if, and only if, neither the source nor the texture pixel is transparent. (Note that the HP ``RasterOp`` specification, on which this is based, specifies that if the source and texture are both all 1s and the command specifies transparent source and opaque texture, the result should be written in the output. We think this is an error in the documentation.) + + +Images +"""""""""""""""""""""""""""""""""""" + +Similar to the high-level interface for fill and stroke graphics, a high-level interface exists for bitmap images. The procedures in this part of the interface are optional. + +Bitmap images come in a variety of types, corresponding closely (but not precisely) to the PostScript ImageTypes. The generic or common part of all bitmap images is defined by: + +.. code-block:: c + + typedef struct { + const gx_image_type_t *type; + gs_matrix ImageMatrix; + } gs_image_common_t; + +Bitmap images that supply data (all image types except image_type_from_device (2)) are defined by: + +.. code-block:: c + + #define gs_image_max_components 5 + typedef struct { + << gs_image_common_t >> + int Width; + int Height; + int BitsPerComponent; + float Decode[gs_image_max_components * 2]; + bool Interpolate; + } gs_data_image_t; + +Images that supply pixel (as opposed to mask) data are defined by: + + +.. code-block:: c + + typedef enum { + /* Single plane, chunky pixels. */ + gs_image_format_chunky = 0, + /* num_components planes, chunky components. */ + gs_image_format_component_planar = 1, + /* BitsPerComponent * num_components planes, 1 bit per plane */ + gs_image_format_bit_planar = 2 + } gs_image_format_t; + typedef struct { + << gs_data_image_t >> + const gs_color_space *ColorSpace; + bool CombineWithColor; + } gs_pixel_image_t; + +Ordinary PostScript Level 1 or Level 2 (ImageType 1) images are defined by: + +.. code-block:: c + + typedef enum { + /* No alpha. */ + gs_image_alpha_none = 0, + /* Alpha precedes color components. */ + gs_image_alpha_first, + /* Alpha follows color components. */ + gs_image_alpha_last + } gs_image_alpha_t; + typedef struct { + << gs_pixel_image_t >> + bool ImageMask; + bool adjust; + gs_image_alpha_t Alpha; + } gs_image1_t; + typedef gs_image1_t gs_image_t; + + +Of course, standard PostScript images don't have an alpha component. For more details, consult the source code in ``gsiparam.h`` and ``gsiparm*.h``, which define parameters for an image. + +The ``begin[_typed_]image`` driver procedures create image enumeration structures. The common part of these structures consists of: + + +.. code-block:: c + + typedef struct gx_image_enum_common_s { + const gx_image_type_t *image_type; + const gx_image_enum_procs_t *procs; + gx_device *dev; + gs_id id; + int num_planes; + int plane_depths[gs_image_max_planes]; /* [num_planes] */ + int plane_widths[gs_image_max_planes] /* [num_planes] */ + } gx_image_enum_common_t; + + +where ``procs`` consists of: + +.. code-block:: c + + typedef struct gx_image_enum_procs_s { + + /* + * Pass the next batch of data for processing. + */ + #define image_enum_proc_plane_data(proc)\ + int proc(gx_device *dev,\ + gx_image_enum_common_t *info, const gx_image_plane_t *planes,\ + int height) + + image_enum_proc_plane_data((*plane_data)); + + /* + * End processing an image, freeing the enumerator. + */ + #define image_enum_proc_end_image(proc)\ + int proc(gx_device *dev,\ + gx_image_enum_common_t *info, bool draw_last) + + image_enum_proc_end_image((*end_image)); + + /* + * Flush any intermediate buffers to the target device. + * We need this for situations where two images interact + * (currently, only the mask and the data of ImageType 3). + * This procedure is optional (may be 0). + */ + #define image_enum_proc_flush(proc)\ + int proc(gx_image_enum_common_t *info) + + image_enum_proc_flush((*flush)); + + } gx_image_enum_procs_t; + + +In other words, ``begin[_typed]_image`` sets up an enumeration structure that contains the procedures that will process the image data, together with all variables needed to maintain the state of the process. Since this is somewhat tricky to get right, if you plan to create one of your own you should probably read an existing implementation of ``begin[_typed]_image``, such as the one in ``gdevbbox.c``. + +The data passed at each call of ``image_plane_data`` consists of one or more planes, as appropriate for the type of image. ``begin[_typed]_image`` must initialize the ``plane_depths`` array in the enumeration structure with the depths (bits per element) of the planes. The array of ``gx_image_plane_t`` structures passed to each call of ``image_plane_data`` then defines where the data are stored, as follows: + + +.. code-block:: c + + typedef struct gx_image_plane_s { + const byte *data; + int data_x; + uint raster; + } gx_image_plane_t; + + +``int (*begin_typed_image)(gx_device *dev, const gs_imager_state *pis, const gs_matrix *pmat, const gs_image_common_t *pim, gs_int_rect *prect, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *memory, gx_image_enum_common_t **pinfo) [OPTIONAL]`` + Begin the transmission of an image. Zero or more calls of the ``image_plane_data`` function supplied in the returned image enumerator will follow, and then a call of ``end_image``. The parameters of ``begin_typed_image`` are as follows: + + + + .. list-table:: + :widths: 15 85 + :header-rows: 0 + + * - ``pis`` + - pointer to an imager state. + The only relevant elements of the imager state are the CTM (coordinate transformation matrix), + + the logical operation (``RasterOp`` or transparency), and the color rendering information. + + For mask images, if ``pmat`` is not NULL and the color is pure, ``pis`` may be NULL. + + * - ``pmat`` + - pointer to a ``gs_matrix`` structure that defines the image transformation matrix. + + If ``pis`` is non-NULL, and ``pmat`` is NULL, then the ``ctm`` from ``pis`` should be used. + + * - ``pim`` + - pointer to the ``gs_image_t`` structure that defines the image parameters. + + * - ``prect`` + - if not NULL, defines a subrectangle of the image; + + only the data for this subrectangle will be passed to ``image_plane_data``, + + and only this subrectangle should be drawn. + + * - ``pdcolor`` + - defines a drawing color, only needed for masks or if ``CombineWithColor`` is true. + + * - ``pcpath`` + - if not NULL, defines an optional clipping path. + + * - ``memory`` + - defines the allocator to be used for allocating bookkeeping information. + + * - ``pinfo`` + - the implementation should return a pointer to its state structure here. + + + ``begin_typed_image`` is expected to allocate a structure for its bookkeeping needs, using the allocator defined by the memory parameter, and return it in ``*pinfo``. ``begin_typed_image`` should not assume that the structures in ``*pim``, ``*prect``, or ``*pdcolor`` will survive the call on ``begin_typed_image`` (except for the color space in ``*pim->ColorSpace``): it should copy any necessary parts of them into its own bookkeeping structure. It may, however, assume that ``*pis``, ``*pcpath``, and of course ``*memory`` will live at least until ``end_image`` is called. + + ``begin_typed_image`` returns 0 normally, or 1 if the image does not need any data. In the latter case, ``begin_typed_image`` does not allocate an enumeration structure. + + +The format of the image (how pixels are represented) is given by ``pim->format``. + +The actual transmission of data uses the procedures in the enumeration structure, not driver procedures, since the handling of the data usually depends on the image type and parameters rather than the device. These procedures are specified as follows. + + +``int (*image_plane_data)(gx_device *dev, gx_image_enum_common_t *info, const gx_image_plane_t *planes, int height)`` + This call provides more of the image source data: specifically, height rows, with Width pixels supplied for each row. + + The data for each row are packed big-endian within each byte, as for copy_color. The ``data_x`` (starting X position within the row) and raster (number of bytes per row) are specified separately for each plane, and may include some padding at the beginning or end of each row. Note that for non-mask images, the input data may be in any color space and may have any number of bits per component (1, 2, 4, 8, 12); currently mask images always have 1 bit per component, but in the future, they might allow multiple bits of alpha. Note also that each call of ``image_plane_data`` passes complete pixels: for example, for a chunky image with 24 bits per pixel, each call of ``image_plane_data`` passes 3N bytes of data (specifically, 3 × Width × height). + + The interpretation of planes depends on the format member of the ``gs_image[_common]_t`` structure: + + If the format is ``gs_image_format_chunky``, ``planes[0].data`` points to data in "chunky" format, in which the components follow each other (for instance, RGBRGBRGB....) + + If the format is ``gs_image_format_component_planar``, ``planes[0 .. N-1].data`` point to data for the N components (for example, N=3 for RGB data); each plane contains samples for a single component, for instance, RR..., GG..., BB.... Note that the planes are divided by component, not by bit: for example, for 24-bit RGB data, N=3, with 8-bit values in each plane of data. + + If the format is ``gs_image_format_bit_planar``, ``planes[0 .. N*B-1].data`` point to data for the N components of B bits each (for example, N=3 and B=4 for RGB data with 4 bits per component); each plane contains samples for a single bit, for instance, R0 R1 R2 R3 G0 G1 G2 G3 B0 B1 B2 B3. + + Note that the most significant bit of each plane comes first. + + If, as a result of this call, ``image_plane_data`` has been called with all the data for the (sub-)image, it returns 1; otherwise, it returns 0 or an error code as usual. + + ``image_plane_data``, unlike most other procedures that take bitmaps as arguments, does not require the data to be aligned in any way. + + Note that for some image types, different planes may have different numbers of bits per pixel, as defined in the ``plane_depths`` array. + + +``int (*end_image)(gx_device *dev, void *info, bool draw_last)`` + Finish processing an image, either because all data have been supplied or because the caller has decided to abandon this image. ``end_image`` may be called at any time after ``begin_typed_image``. It should free the info structure and any subsidiary structures. If ``draw_last`` is true, it should finish drawing any buffered lines of the image. + + +.. note:: + + - While there will almost never be more than one image enumeration in progress -- that is, after a ``begin_typed_image``, ``end_image`` will almost always be called before the next ``begin_typed_image`` -- driver code should not rely on this property; in particular, it should store all information regarding the image in the info structure, not in the driver structure. + + - If ``begin_typed_image`` saves its parameters in the info structure, it can decide on each call whether to use its own algorithms or to use the default implementation. (It may need to call ``gx_default_begin/end_image`` partway through.) + + +Text +"""""""""""""""""""""""""""""""""""" + +The third high-level interface handles text. As for images, the interface is based on creating an enumerator which then may execute the operation in multiple steps. As for the other high-level interfaces, the procedures are optional. + + +``int (*text_begin)(gx_device *dev, gs_imager_state *pis, const gs_text_params_t *text, gs_font *font, const gx_clip_path *pcpath, gs_text_enum_t **ppte) [OPTIONAL]`` + Begin processing text, by creating a state structure and storing it in ``*ppte``. The parameters of ``text_begin`` are as follows: + + .. list-table:: + :widths: 15 85 + :header-rows: 0 + + * - ``dev`` + - The usual pointer to the device. + * - ``pis`` + - A pointer to an imager state. All elements may be relevant, depending on how the text is rendered. + * - ``text`` + - A pointer to the structure that defines the text operation and parameters. See ``gstext.h`` for details. + * - ``font`` + - Defines the font for drawing. + * - ``pcpath`` + - If not ``NULL``, defines an optional clipping path. Only relevant if the text operation includes ``TEXT_DO_DRAW``. + * - ``ppte`` + - The implementation should return a pointer to its state structure here. + + + ``text_begin`` must allocate a structure for its bookkeeping needs, using the allocator used by the graphics state, and return it in ``*ppte``. ``text_begin`` may assume that the structures passed as parameters will survive until text processing is complete. + + If the text operation includes ``TEXT_DO...PATH`` then the character outline will be appended to the current path in the ``pgs``. The current point of that path indicates where drawing should occur and will be updated by the string width (unless the text operation includes ``TEXT_DO_NONE``). + + If the text operation includes ``TEXT_DO_DRAW`` then the text color will be taken from the current colour in the graphics state. (Otherwise no colour is required). + + The bookkeeping information will be allocated using the memory allocator from the graphics state. + + Clients should not call the driver text_begin procedure directly. Instead, they should call ``gx_device_text_begin``, which takes the same parameters and also initializes certain common elements of the text enumeration structure, or ``gs_text_begin``, which takes many of the parameters from a graphics state structure. For details, see ``gstext.h``. + + The actual processing of text uses the procedures in the enumeration structure, not driver procedures, since the handling of the text may depend on the font and parameters rather than the device. Text processing may also require the client to take action between characters, either because the client requested it (``TEXT_INTERVENE`` in the operation) or because rendering a character requires suspending text processing to call an external package such as the PostScript interpreter. (It is a deliberate design decision to handle this by returning to the client, rather than calling out of the text renderer, in order to avoid potentially unknown stack requirements.) Specifically, the client must call the following procedures, which in turn call the procedures in the text enumerator. + + +``int gs_text_process(gs_text_enum_t *pte)`` + Continue processing text. This procedure may return 0 or a negative error code as usual, or one of the following values (see ``gstext.h`` for details). + + .. list-table:: + :widths: 30 70 + :header-rows: 0 + + * - TEXT_PROCESS_RENDER + - The client must cause the current character to be rendered. + + This currently only is used for PostScript Type 0-4 fonts and their CID-keyed relatives. + + * - TEXT_PROCESS_INTERVENE + - The client has asked to intervene between characters. This is used for ``cshow`` and ``kshow``. + + + +``int gs_text_release(gs_gstate * pgs, gs_text_enum_t *pte, client_name_t cname)`` + Finish processing text and release all associated structures. Clients must call this procedure after ``gs_text_process`` returns 0 or an error, and may call it at any time. + + There are numerous other procedures that clients may call during text processing. See ``gstext.h`` for details. + + + .. note:: + + Unlike many other optional procedures, the default implementation of ``text_begin`` cannot simply return: like the default implementation of ``begin[_typed]_image``, it must create and return an enumerator. Furthermore, the implementation of the process procedure (in the enumerator structure, called by ``gs_text_process``) cannot simply return without doing anything, even if it doesn't want to draw anything on the output. See the comments in ``gxtext.h`` for details. + + +Unicode support for high level (vector) devices +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Implementing a new high level (also known as vector) device, one may need to translate Postscript character codes into Unicode. This can be done pretty simply. + +For translating a Postscript text you need to implement the device virtual function ``text_begin``. It should create a new instance of ``gs_text_enum_t`` in the heap (let its pointer be ``pte``), and assign a special function to ``gs_text_enum_t::procs.process``. The function will receive ``pte``. It should take the top level font from ``pte->orig_font``, and iterate with ``font->procs.next_char_glyph(pte, ..., &glyph)``. The last argument receives a ``gs_glyph`` value, which encodes a Postscript character name or CID (and also stores it into ``pte->returned.current_glyph``). Then obtain the current subfont with ``gs_text_current_font(pte)`` (it can differ from the font) and call ``subfont->procs.decode_glyph(subfont, glyph)``. The return value will be an Unicode code, or ``GS_NO_CHAR`` if the glyph can't be translated to Unicode. + + +Reading bits back +~~~~~~~~~~~~~~~~~~~ + +``int (*get_bits_rectangle)(gx_device *dev, const gs_int_rect *prect, gs_get_bits_params_t *params) [OPTIONAL]`` + Read a rectangle of bits back from the device. The ``params`` structure consists of: + + .. list-table:: + :widths: 30 70 + :header-rows: 0 + + * - ``options`` + - the allowable formats for returning the data + * - ``data[32]`` + - pointers to the returned data + * - ``x_offset`` + - the X offset of the first returned pixel in data + * - ``raster`` + - the distance between scan lines in the returned data + + ``options`` is a bit mask specifying what formats the client is willing to accept. (If the client has more flexibility, the implementation may be able to return the data more efficiently, by avoiding representation conversions.) The options are divided into groups: + + *alignment* + Specifies whether the returned data must be aligned in the normal manner for bitmaps, or whether unaligned data are acceptable. + + *pointer or copy* + Specifies whether the data may be copied into storage provided by the client and/or returned as pointers to existing storage. (Note that if copying is not allowed, it is much more likely that the implementation will return an error, since this requires that the client accept the data in the implementation's internal format.) + + *X offset* + Specifies whether the returned data must have a specific X offset (usually zero, but possibly other values to avoid skew at some later stage of processing) or whether it may have any X offset (which may avoid skew in the ``get_bits_rectangle`` operation itself). + + *raster* + Specifies whether the raster (distance between returned scan lines) must have its standard value, must have some other specific value, or may have any value. The standard value for the raster is the device width padded out to the alignment modulus when using pointers, or the minimum raster to accommodate the X offset + width when copying (padded out to the alignment modulus if standard alignment is required). + + *format* + Specifies whether the data are returned in chunky (all components of a single pixel together), component-planar (each component has its own scan lines), or bit-planar (each bit has its own scan lines) format. + + *color space* + Specifies whether the data are returned as native device pixels, or in a standard color space. Currently the only supported standard space is RGB. + + *standard component depth* + Specifies the number of bits per component if the data are returned in the standard color space. (Native device pixels use ``dev->color_info.depth`` bits per pixel.) + + *alpha* + Specifies whether alpha channel information should be returned as the first component, the last component, or not at all. Note that for devices that have no alpha capability, the returned alpha values will be all 1s. + + +The client may set more than one option in each of the above groups; the implementation will choose one of the selected options in each group to determine the actual form of the returned data, and will update ``params[].options`` to indicate the form. The returned ``params[].options`` will normally have only one option set per group. + +For further details on params, see ``gxgetbit.h``. For further details on options, see ``gxbitfmt.h``. + +Define ``w = prect->q.x - prect->p.x, h = prect->q.y - prect->p.y``. If the bits cannot be read back (for example, from a printer), return ``gs_error_unknownerror``; if raster bytes is not enough space to hold ``offset_x + w pixels``, or if the source rectangle goes outside the device dimensions (``p.x < 0 || p.y < 0 || q.x > dev->width || q.y > dev->height``), return ``gs_error_rangecheck``; if any regions could not be read, return ``gs_error_ioerror`` if unpainted is ``NULL``, otherwise the number of rectangles (see below); otherwise return 0. + +The caller supplies a buffer of ``raster × h`` bytes starting at ``data[0]`` for the returned data in chunky format, or ``N`` buffers of ``raster × h`` bytes starting at ``data[0]`` through ``data[N-1]`` in planar format where ``N`` is the number of components or bits. The contents of the bits beyond the last valid bit in each scan line (as defined by ``w``) are unpredictable. ``data`` need not be aligned in any way. If ``x_offset`` is non-zero, the bits before the first valid bit in each scan line are undefined. If the implementation returns pointers to the ``data``, it stores them into ``data[0]`` or ``data[0..N-1]``. + + +Parameters +~~~~~~~~~~~~~~~~~~~ + +Devices may have an open-ended set of parameters, which are simply pairs consisting of a name and a value. The value may be of various types: integer (int or long), boolean, float, string, name, NULL, array of integer, array of float, or arrays or dictionaries of mixed types. For example, the ``Name`` of a device is a string; the ``Margins`` of a device is an array of two floats. See ``gsparam.h`` for more details. + +If a device has parameters other than the ones applicable to all devices (or, in the case of printer devices, all printer devices), it must provide ``get_params`` and ``put_params`` procedures. If your device has parameters beyond those of a straightforward display or printer, we strongly advise using the ``get_params`` and ``put_params`` procedures in an existing device (for example, ``gdevcdj.c`` or ``gdevbit.c``) as a model for your own code. + + +``int (*get_params)(gx_device *dev, gs_param_list *plist) [OPTIONAL]`` + Read the parameters of the device into the parameter list at plist, using the ``param_write_*`` macros or procedures defined in ``gsparam.h``. + +``int (*get_hardware_params)(gx_device *dev, gs_param_list *plist) [OPTIONAL]`` + Read the hardware-related parameters of the device into the parameter list at plist. These are any parameters whose values are under control of external forces rather than the program -- for example, front panel switches, paper jam or tray empty sensors, etc. If a parameter involves significant delay or hardware action, the driver should only determine the value of the parameter if it is "requested" by the ``gs_param_list [param_requested(plist, key_name)]``. This function may cause the asynchronous rendering pipeline (if enabled) to be drained, so it should be used sparingly. + +``int (*put_params)(gx_device *dev, gs_param_list *plist) [OPTIONAL]`` + Set the parameters of the device from the parameter list at plist, using the ``param_read_*`` macros/procedures defined in ``gsparam.h``. All ``put_params`` procedures must use a "two-phase commit" algorithm; see ``gsparam.h`` for details. + +Default color rendering dictionary (CRD) parameters +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Drivers that want to provide one or more default CIE color rendering dictionaries (CRDs) can do so through ``get_params``. To do this, they create the CRD in the usual way (normally using the ``gs_cie_render1_build`` and ``_initialize`` procedures defined in ``gscrd.h``), and then write it as a parameter using ``param_write_cie_render1`` defined in ``gscrdp.h``. However, the ``TransformPQR`` procedure requires special handling. If the CRD uses a ``TransformPQR`` procedure different from the default (identity), the driver must do the following: + +- The ``TransformPQR`` element of the CRD must include a ``proc_name``, and optionally ``proc_data``. The ``proc_name`` is an arbitrary name chosen by the driver to designate the particular ``TransformPQR`` function. It must not be the same as any device parameter name; we strongly suggest it include the device name, for instance, "bitTPQRDefault". + +- For each such named ``TransformPQR`` procedure, the driver's ``get_param`` procedure must provide a parameter of the same name. The parameter value must be a string whose bytes are the actual procedure address. + + +For a complete example, see the ``bit_get_params`` procedure in ``gdevbit.c``. Note that it is essential that the driver return the CRD or the procedure address only if specifically requested (``param_requested(...) > 0``); otherwise, errors will occur. + + + +Device parameters affecting interpretation +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Some parameters have been defined for high level (vector) device drivers which affect the operation of the interpreter. These are documented here so that other devices requiring the same behaviour can use these parameters. + +``/HighLevelDevice`` + True if the device is a high level (vector) device. Currently this controls haltone emission during setpagedevice. Normally ``setpagdevice`` resets the halftone to a default value, which is unfortunate for high-level devices such as :title:`ps2write` and :title:`pdfwrite`, as they are unable to tell that this is caused by ``setpagdevice`` rather than a halftone set by the input file. In order to prevent spurious default halftones being embedded in the output, if ``/HighLevelDevice`` is present and true in the device paramters, then the default halftone will not be set during ``setpagedevice``. Also prevents interpolation of imagemasks during PDF interpretation. + +``/AllowIncrementalCFF`` + :title:`pdfwrite` relies on font processing occuring in a particular order, which may not happen if CFF fonts are downloaded incrementally. Defining this parameter to true will prevent incremental CFF downloading (may raise an error during processing). + +``/AllowPSRepeatFuncs`` + :title:`pdfwrite` emits functions as type 4, and as a result can't convert PostScript functions using the repeat operator into PDF functions. Defining this parameter as true will cause such functions to raise an error during processing. + +``/IsDistiller`` + Defining this parameter as true will result in the operators relating to 'distillerparams' being defined (``setdistillerparams``/``currentdistillerparams``). Some PostScript files behave differently if these operators are present (e.g. rotating the page) so this parameter may be true even if the device is not strictly a Distiller. For example :title:`ps2write` defines this parameter to be true. + +``/PreserveSMask`` + If this parameter is true then the PDF interpreter will not convert ``SMask`` (soft mask, ie transparent) images into opaque images. This should be set to true for devices which can handle transparency (e.g. :title:`pdfwrite`). + +``/PreserveTrMode`` + If this parameter is true then the PDF interpreter will not handle Text Rendering modes by degenerating into a sequence of text operations, but will instead set the ``Tr`` mode, and emit the text once. This value should be true for devices which can handle PDF text rendering modes directly. + +``/WantsToUnicode`` + In general, Unicode values are not of interest to rendering devices, but for high level (aka vector) devices, they can be extremely valuable. If this parameter is defined as true then ``ToUnicode CMaps`` and ``GlyphName2Unicode`` tables will be processed and stored. + + +Page devices +~~~~~~~~~~~~~~ + +``gx_device *(*get_page_device)(gx_device *dev) [OPTIONAL]`` + According to the Adobe specifications, some devices are "page devices" and some are not. This procedure returns NULL if the device is not a page device, or the device itself if it is a page device. In the case of forwarding devices, ``get_page_device`` returns the underlying page device (or NULL if the underlying device is not a page device). + +Miscellaneous +~~~~~~~~~~~~~~~ + +``int (*get_band)(gx_device *dev, int y, int *band_start) [OPTIONAL]`` + If the device is a band device, this procedure stores in ``*band_start`` the scan line (device Y coordinate) of the band that includes the given Y coordinate, and returns the number of scan lines in the band. If the device is not a band device, this procedure returns 0. The latter is the default implementation. + +``void (*get_clipping_box)(gx_device *dev, gs_fixed_rect *pbox) [OPTIONAL]`` + Stores in ``*pbox`` a rectangle that defines the device's clipping region. For all but a few specialized devices, this is *((0,0),(width,height))*. + + +Device Specific Operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to enable the provision of operations that make sense only to a small range of devices/callers, we provide an extensible function. The operation to perform is specified by an integer, taken from an enumeration in ``gxdevsop.h``. + +A typical user of this function might make a call to detect whether a device works in a particular way (such as whether it has a particular color mapping) to enable an optimisation elsewhere. Sometimes it may be used to detect a particular piece of functionality (such as whether ``copy_plane`` is supported); in other cases it may be used both to detect the presence of other functionality and to perform functions as well (such as with the pdf specific pattern management calls - moved here from their own dedicated device function). + +This function is designed to be easy to chain through multiple levels of device without each intermediate device needing to know about the full range of operations it may be asked to perform. + +``int (*dev_spec_op)(gx_device *dev, int dso, void *data, int size) [OPTIONAL]`` + Perform device specific operation ``dso``. Returns ``gs_error_undefined`` for an unknown (or unsupported operation), other negative values for errors, and (``dso`` specific) non-negative values to indicate success. For details of the meanings of ``dso``, ``data`` and ``size``, see ``gxdevsop.h``. + + +Tray selection +---------------------- + +The logic for selecting input trays, and modifying other parameters based on tray selection, can be complex and subtle, largely thanks to the requirement to be compatible with the PostScript language ``setpagedevice`` mechanism. This section will describe recipes for several common scenarios for tray selection, with special attention to the how the overall task factors into configuration options, generic logic provided by the PostScript language (or not, if the device is used with other PDL's), and implementation of the ``put_param`` / ``get_param`` device functions within the device. + +In general, tray selection is determined primarily through the ``setpagedevice`` operator, which is part of the PostScript runtime. Ghostscript attempts to be as compatible as is reasonable with the PostScript standard, so for more details, see the description in the PostScript language specifications, including the "supplements", which tend to have more detail about ``setpagedevice`` behavior than the PLRM book itself. + +The first step is to set up an ``/InputAttributes`` dictionary matching the trays and so on available in the device. The standard Ghostscript initialization files set up a large ``InputAttributes`` dictionary with many "known" page sizes (the full list is in ``gs_statd.ps``, under ``.setpagesize``). It's possible to edit this list in the Ghostscript source, of course, but most of the time it is better to execute a snippet of PostScript code after the default initialization but before sending any actual jobs. + +Simply setting a new ``/InputAttributes`` dictionary with ``setpagedevice`` will not work, because the the language specification for ``setpagedevice`` demands a "merging" behavior - paper tray keys present in the old dictionary will be preserved even if the key is not present in the new ``/InputAttributes`` dictionary. Here is a sample invocation that clears out all existing keys, and installs three new ones: a US letter page size for trays 0 and 1, and 11x17 for tray 1. Note that you must add at least one valid entry into the ``/InputAttributes`` dictionary; if all are null, then the ``setpagedevice`` will fail with a ``/configurationerror``. + + +.. code-block:: postscript + + << /InputAttributes + currentpagedevice /InputAttributes get + dup { pop 1 index exch null put } forall + + dup 0 << /PageSize [612 792] >> put + dup 1 << /PageSize [612 792] >> put + dup 2 << /PageSize [792 1224] >> put + >> setpagedevice + +After this code runs, then requesting a letter page size (612x792 points) from ``setpagedevice`` will select tray 0, and requesting an 11x17 size will select tray 2. To explicitly request tray 1, run: + +.. code-block:: postscript + + << /PageSize [612 792] /MediaPosition 1 >> setpagedevice + + +At this point, the chosen tray is sent to the device as the (nonstandard) ``%MediaSource`` device parameter. Devices with switchable trays should implement this device parameter in the ``put_params`` procedure. Unlike the usual protocol for device parameters, it is not necessary for devices to also implement ``get_params`` querying of this paramter; it is effectively a write-only communication from the language to the device. Currently, among the devices that ship with Ghostscript, only PCL (``gdevdjet.c``) and PCL/XL (``gdevpx.c``) implement this parameter, but that list may well grow over time. + +If the device has dynamic configuration of trays, etc., then the easiest way to get that information into the tray selection logic is to send a ``setpagedevice`` request (if using the standard API, then using ``gsapi_run_string_continue``) to update the ``/InputAttributes`` dictionary immediately before beginning a job. + + +Tray rotation and the LeadingEdge parameter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Large, sophisticated printers often have multiple trays supporting both short-edge and long-edge feed. For example, if the paper path is 11 inches wide, then 11x17 pages must always print short-edge, but letter size pages print with higher throughput if fed from long-edge trays. Generally, the device will expect the rasterized bitmap image to be rotated with respect to the page, so that it's always the same orientation with respect to the paper feed direction. + +The simplest way to achieve this behavior is to call ``gx_device_request_leadingedge`` to request a ``LeadingEdge`` value ``LeadingEdge`` field in the device structure based on the ``%MediaSource`` tray selection index and knowledge of the device's trays. The default ``put_params`` implementation will then handle this request (it's done this way to preserve the transactional semantics of ``put_params``; it needs the new value, but the changes can't actually be made until all params succeed). For example, if tray 0 is long-edge, while trays 1 and 2 are short-edge, the following code outline should select the appropriate rotation: + +.. code-block:: c + + my_put_params(gx_device *pdev, gs_param_list *plist) { + my_device *dev = (my_device *)pdev; + int MediaSource = dev->myMediaSource; + + code = param_read_int(plist, "%MediaSource", &MediaSource); + + switch (MediaSource) { + case 0: + gx_device_req_leadingedge(dev, 1); + break; + case 1: + case 2: + gx_device_req_leadingedge(dev, 0); + break; + } + ...call default put_params, which makes the change... + + dev->myMediaSource = MediaSource; + return 0; + } + +Ghostscript also supports explicit rotation of the page through setting the ``/LeadingEdge`` parameter with ``setpagedevice``. The above code snippet will simply override this request. To give manual setting through ``setpagedevice`` priority, don't change the ``LeadingEdge`` field in the device if its ``LEADINGEDGE_SET_MASK`` bit is set. In other words, simply enclose the above switch statement inside an ``if (!(dev->LeadingEdge & LEADINGEDGE_SET_MASK) { ... }`` statement. + +Interaction between LeadingEdge and PageSize +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As of LanguageLevel 3, PostScript now has two mechanisms for rotating the imaging of the page: the ``LeadingEdge`` parameter described in detail above, and the automatic rotation as enabled by the ``/PageSize`` page device parameter (described in detail in Table 6.2 of the PLRM3). Briefly, the ``PageSize`` autorotation handles the case where the page size requested in ``setpagedevice`` matches the swapped size of the paper source (as set in the ``InputAttributesDictionary``). This mechanism can be, and has been, used to implement long-edge feed, but has several disadvantages. Among other things, it's overly tied to the PostScript language, while the device code above will work with other languages. Also, it only specifies one direction of rotation (90 degrees counterclockwise). Thus, given the choice, ``LeadingEdge`` is to be preferred. + +If ``PageSize`` is used, the following things are different: + +- The ``PageSize`` array in ``InputAttributes`` is swapped, so it is ``[long short]``. + +- The ``.MediaSize`` device parameter is similarly swapped. + +- The initial matrix established by the device through the ``get_initial_matrix`` procedure is the same as for the non-rotated case. + +- The CTM rotation is done in the ``setpagedevice`` implementation. + + +.. include:: footer.rst diff --git a/doc/src/Fonts.rst b/doc/src/Fonts.rst new file mode 100644 index 00000000..bcba4890 --- /dev/null +++ b/doc/src/Fonts.rst @@ -0,0 +1,419 @@ +.. title:: Fonts and Font Facilities Supplied with Ghostscript + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Fonts.htm: + + +Fonts and Font Facilities Supplied with Ghostscript +====================================================== + + + + +About Ghostscript fonts +--------------------------- + +Ghostscript is distributed with two kinds of files related to fonts: + +- The fonts themselves in individual files. + +- A file "Fontmap" that defines for Ghostscript which file represents which font. + +Additionally, the file ``cidfmap`` can be used to create substitutes for ``CIDFonts`` referenced by name in Postscript and PDF jobs. See the section on CID Font Substitution for details. + +.. note:: + + Care must be exercised since poor or incorrect output may result from inappropriate ``CIDFont`` substitution. We therefore strongly recommend embedding CIDFonts in your Postscript and PDF files if at all possible. + +The "base 35" fonts required for Postscript (and "base 14" required for PDF) are Postscript Type 1 font files. + +When Ghostscript needs a font, it must have some way to know where to look for it: that's the purpose of the ``Fontmap`` file, which associates the names of fonts such as ``/Times-Roman`` with the names of font files, such as ``n021003l.pfb``. ``Fontmap`` can also create aliases for font names, so that for instance, ``/NimbusNo9L-Regu`` means the same font as ``/Times-Roman``. + +Where a mapping in ``Fontmap`` maps a font name to a ``path/file``, the directory containing the font file is automatically added to the ``permit file read`` list. For example: + +.. code-block:: postscript + + /Arial (/usr/share/fonts/truetype/msttcorefonts/arial.ttf) ; + +will result in the path ``/usr/share/fonts/truetype/msttcorefonts/`` being added to the permit file read list. This is done on the basis that font files are often grouped in common directories, and rather than risk the file permissions lists being swamped with (potentially) hundreds of individual files, it makes sense to add the directories. + + +.. note:: + + ``Fontmap`` is processed (and the paths added to the file permissions list) during initialisation of the Postscript interpreter, so any attempt by a Postscript job to change the font map cannot influence the file permissions list. + + + +Ghostscript's free fonts +------------------------------ + +35 commercial-quality Type 1 basic PostScript fonts -- Times, Helvetica, Courier, Symbol, etc. -- contributed by `URW++ Design and Development Incorporated`_, of Hamburg, Germany. ``Fontmap`` names them all. + + + +How Ghostscript gets fonts when it runs +--------------------------------------------------- + +Fonts occupy about 50KB each, so Ghostscript doesn't load them all automatically when it runs. Instead, as part of normal initialization Ghostscript runs a file ``gs_fonts.ps``, which arranges to load fonts on demand using information from the font map. To preload all of the known fonts, invoke the procedure: + + +.. code-block:: postscript + + loadallfonts + +The file ``lib/prfont.ps`` contains code to print a sample page of a font. Load this program by including it in the ``gs`` command line or by invoking: + +.. code-block:: bash + + (prfont.ps) run + +Then to produce a sampler of a particular font ``XYZ``, invoke: + +.. code-block:: postscript + + /XYZ DoFont + +For example, + +.. code-block:: postscript + + /Times-Roman DoFont + +For more information about how Ghostscript loads fonts during execution, see :ref:`Font lookup<Use_Font lookup>`. + + +.. _Fonts_Add: + +Adding your own fonts +--------------------------------------------------- + +Ghostscript can use any Type 0, 1, 3, 4, or 42 font acceptable to other PostScript language interpreters or to ATM, including MultiMaster fonts. Ghostscript can also use TrueType font files. + +To add fonts of your own, you must edit ``Fontmap`` to include at the end an entry for your new font; the format for entries is documented in ``Fontmap`` itself. Since later entries in ``Fontmap`` override earlier entries, a font you add at the end supersedes any corresponding fonts supplied with Ghostscript and defined earlier in the file. To ensure correct output, it is vital that entries for the "base 35" fonts remain intact in the ``Fontmap`` file. + +In the PC world, Type 1 fonts are customarily given names ending in ``.PFA`` or ``.PFB``. Ghostscript can use these directly: you just need to make the entry in ``Fontmap``. If you want to use with Ghostscript a commercial Type 1 font (such as fonts obtained in conjunction with Adobe Type Manager), please read carefully the license that accompanies the font to satisfy yourself that you may do so legally; we take no responsibility for any possible violations of such licenses. The same applies to TrueType fonts. + +Converting BDF fonts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. note:: + + This is deprecated. + +Ghostscript provides a way to construct a (low-quality) Type 1 font from a bitmap font in the BDF format popular in the Unix world. The shell script bdftops (Unix) or the command file ``bdftops.bat`` (DOS) converts a BDF file to a scalable outline using ``bdftops.ps`` . Run the shell command: + +.. code-block:: bash + + bdftops BDF_filename [AFM_file1_name ...] gsf_filename fontname + UniqueID [XUID] [encodingname] + + +The arguments have these meanings: + + +.. list-table:: + :header-rows: 0 + + * - ``BDF_filename`` + - Input bitmap file in BDF format + - + * - ``AFM_file1_name`` + - AFM files giving metrics + - (Optional) + * - ``gsf_filename`` + - Output file + - + * - ``fontname`` + - Name of the font + - + * - ``UniqueID`` + - UniqueID (:ref:`as described below<Fonts_UniqueIDs>`) + - + * - ``XUID`` + - XUID, in the form n1.n2.n3... (:ref:`as described below<Fonts_UniqueIDs>`) + - (Optional) + * - ``encodingname`` + - "StandardEncoding" (the default), "ISOLatin1Encoding", "SymbolEncoding", "DingbatsEncoding" + - (Optional) + +For instance: + +.. code-block:: postscript + + bdftops pzdr.bdf ZapfDingbats.afm pzdr.gsf ZapfDingbats 4100000 1000000.1.41 + +Then make an entry in ``Fontmap`` for the ``.gsf`` file (``pzdr.gsf`` in the example) as :ref:`described above<Fonts_Add>`. + + + +For developers only +--------------------- + +The rest of this document is very unlikely to be of value to ordinary users. + +Contents of fonts +~~~~~~~~~~~~~~~~~~~~ + +As noted above, Ghostscript accepts fonts in the same formats as PostScript interpreters. Type 0, 1, and 3 fonts are documented in the PostScript Language Reference Manual (Second Edition); detailed documentation for Type 1 fonts appears in a separate Adobe book. Type 2 (compressed format) fonts are documented in separate Adobe publications. Type 4 fonts are not documented anywhere; they are essentially Type 1 fonts with a BuildChar or BuildGlyph procedure. Types 9, 10, and 11 (CIDFontType 0, 1, and 2) and Type 32 (downloaded bitmap) fonts are documented in Adobe supplements. Type 42 (encapsulated TrueType) fonts are documented in an Adobe supplement; the TrueType format is documented in publications available from Apple and Microsoft. Ghostscript does not support Type 14 (Chameleon) fonts, which use a proprietary Adobe format. + + + +.. _Fonts_UniqueIDs: + +Font names and unique IDs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you create your own fonts and will use them only within your own organization, you should use ``UniqueID`` values between ``4000000`` and ``4999999``. + +If you plan to distribute fonts, ask Adobe to assign you some ``UniqueIDs`` and also an ``XUID`` for your organization. Contact: + +:: + + Unique ID Coordinator + Adobe Developers Association + Adobe Systems, Inc. + 345 Park Avenue + San Jose, CA 95110-2704 + +1-408-536-9000 telephone (ADA) + +1-408-536-6883 fax + fontdev-person@adobe.com + + +The XUID is a Level 2 PostScript feature that serves the same function as the ``UniqueID``, but is not limited to a single 24-bit integer. The ``bdftops`` program creates ``XUIDs`` of the form "``[-X- 0 -U-]``" where "``-X-``" is the organization ``XUID`` and "``-U-``" is the ``UniqueID``. (Aladdin Enterprises' organization XUID, which appears in a few places in various font-related files distributed with Ghostscript, is 107; do not use this for your own fonts that you distribute.) + + + + + + + + +.. Note this was originally on the Use.htm page + +.. _Fonts FAPI: + + + + +Running Ghostscript with third-party font renderers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Font API (FAPI) is a feature which allows to attach third-party font renderers to Ghostscript. This section explains how to run Ghostscript with third-party font renderers, such as UFST. + + +.. note:: FreeType is now the default font renderer for Ghostscript. + + +.. note:: + + To run Ghostscript with UFST you need a license from Monotype Imaging. Please ignore issues about UFST if you haven't got it. + +.. important:: + + Third-party font renderers may be incompatible with devices that can embed fonts in their output (such as pdfwrite), because such renderers may store fonts in a form from which Ghostscript cannot get the necessary information for embedding, for example, the Microtype fonts supplied with the UFST. Ghostscript can be configured to disable such renderers when such a device is being used. + +As of Ghostscript version 9.0, Ghostscript uses Freetype 2.4.x as the default font scaler/renderer. + +With this change, we added a new switch:``-dDisableFAPI=true`` to revert to the older behavior, just in case serious regression happens that cannot be resolved in a timely manner. It is intended that this switch will be removed once the FAPI/Freetype implementation has proven itself robust and reliable in the "real world". + +With version 9.18 released we have, for some time, regarded FAPI/Freetype as being the canonical glyph rendering solution for Ghostscript and associated products, and the non-FAPI rendering to be deprecated. As such, the ``-dDisableFAPI=true`` option is also considered deprecated, and should be expected to be removed shortly after the next release. + +To run Ghostscript with UFST, you first need to :ref:`build Ghostscript with the UFST bridge<Make_USFTBuild>`. Both bridges may run together. + +There are 2 ways to handle fonts with a third-party font renderer (FAPI). First, you can substitute any FAPI-handled font to a resident PostScript font, using special map files ``FAPIfontmap`` and ``FAPIcidfmap``. Second, you can redirect PostScript fonts to FAPI, setting entries in ``FAPIconfig`` file. + +Names ``FAPIfontmap``, ``FAPIcidfmap``, ``FAPIconfig`` in this text actually are placeholders, which may be substituted with command line arguments : ``-sFAPIfontmap=name1 -sFAPIcidfmap=name2 -sFAPIconfig=name3``. Ghostscript searches the specified file names as explained in How Ghostscript finds files. Default values for these arguments are equal to argument names. When building Ghostscript with ``COMPILE_INITS=1``, only default values are used. + +Font files, which are being handled with FAPI, may reside in any directory in your hard disk. Paths to them to be specified in ``FAPIfontmap`` and with special command line arguments, explained below. The path may be either absolute or relative. Relative ones are being resolved from the path, which is specified in ``FAPIconfig`` file. + +The file ``FAPIfontmap`` is actually special PostScript code. It may include records of 2 types : general records and FCO records (see below). + +A general record describes a font, which is being rendered with FAPI. They must end with semicolon. Each general record is a pair. The first element of the pair is the font name (the name that PostScript documents use to access the font, which may differ from real name of the font which the font file defines). The second element is a dictionary with entries: + + + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Key + - Type + - Description + * - Path + - string + - Absolute path to font file, or relative path to font file from the FontPath value, being specified in FAPIconfig. + * - FontType + - integer + - PostScript type for this font. Only 1 and 42 are currently allowed. + + Note that this is unrelated to the real type of the font file - the bridge will perform a format conversion. + + * - FAPI + - name + - Name of the renderer to be used with the font. Only /UFST and /FreeType are now allowed. + * - SubfontId + - integer + - (optional) Index of the font in font collection, such as FCO or TTC. + + It is being ignored if Path doesn't specify a collection. + + Note that Free Type can't handle FCO. Default value is 0. + + * - Decoding + - name + - (optional) The name of a Decoding resource to be used with the font. + + If specified, lib/xlatmap (see below) doesn't work for this font. + + +Example of a general FAPI font map record : + +.. code-block:: bash + + /FCO1 << /Path (/AFPL/UFST/fontdata/MTFONTS/PCLPS3/MT1/PCLP3__F.fco) /FontType 1 /FAPI /UFST >> ; + + +FCO records work for UFST only. A group of FCO records start with a line *name* ``ReadFCOfontmap:``, where *name* is a name of a command line argument, which specify a path to an FCO file. The group of FCO records must end with the line ``EndFCOfontmap``. Each record of a group occupy a single line, and contains a number and 1, 2 or 3 names. The number is the font index in the FCO file, the first name is the Postscript font name, the secong is an Encoding resource name, and the third is a decoding resource name. + + +.. note:: + + ``FAPIfontmap`` specifies only instances of Font category. CID fonts to be listed in another map file. + +Ghostscript distribution includes sample map files ``gs/lib/FAPIfontmap, gs/lib/FCOfontmap-PCLPS2, gs/lib/FCOfontmap-PCLPS3, gs/lib/FCOfontmap-PS3``, which may be customized by the user. The last 3 ones include an information about UFST FCO files. + +The file ``FAPIcidfmap`` defines a mapping table for CIDFont resources. It contains records for each CID font being rendered with FAPI. The format is similar to ``FAPIfontmap``, but dictionaries must contain few different entries: + + + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Key + - Type + - Description + * - Path + - string + - Absolute path to font file, or relative path to font file from the ``CIDFontPath`` value, being specified in FAPIconfig. + * - CIDFontType + - integer + - PostScript type for this CID font. + + Only 0, 1 and 2 are currently allowed. + + Note that this is unrelated to the real type of the font file - the bridge will perform format conversion. + + * - FAPI + - name + - Name of the renderer to be used with the font. + + Only /UFST and /FreeType are now allowed. + + * - SubfontId + - integer + - (optional) Index of the font in font collection, such as FCO or TTC. + + It is being ignored if Path doesn't specify a collection. + + Default value is 0. + + * - CSI + - array of 2 elements + - (required) Information for building CIDSystemInfo. + + The first element is a string, which specifies ``Ordering``. + + The second element is a number, which specifies ``Supplement``. + + + +Example of FAPI CID font map record: + +.. code-block:: bash + + /HeiseiKakuGo-W5 << /Path (/WIN2000/Fonts/PMINGLIU.TTF) /CIDFontType 0 /FAPI /UFST /CSI [(Japan1) 2] >> ; + +The control file FAPIconfig defines 4 entries: + + + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Key + - Type + - Description + + * - FontPath + - string + - Absolute path to a directory, which contains fonts. + + Used to resolve relative paths in ``FAPIfontmap``. + + * - CIDFontPath + - string + - Absolute path to a directory, which contains fonts to substitute to CID fonts. + + Used to resolve relative paths in ``FAPIcidfmap``. + + It may be same or different than ``FontPath``. + + * - HookDiskFonts + - array of integers + - List of PS font types to be handled with FAPI. + + This controls other fonts that ones listed in ``FAPIfontmap`` and ``FAPIcidfmap`` - + + such ones are PS fonts installed to Ghostscript with ``lib/fontmap`` or + + with ``GS_FONTPATH``, or regular CID font resources. + + Unlisted font types will be rendered with the native Ghostscript font renderer. + + Only allowed values now are 1,9,11,42. + + Note that 9 and 11 correspond to ``CIDFontType`` 0 and 2. + + * - HookEmbeddedFonts + - array of integers + - List of PS font types to be handled with FAPI. + + This controls fonts being embedded into a document - either fonts or CID font resources. + + Unlisted font types will be rendered with the native Ghostscript font renderer. + + Only allowed values now are 1,9,11,42. + + Note that 9 and 11 correspond to ``CIDFontType`` 0 and 2. + + +Ghostscript distribution includes sample config files ``gs/lib/FAPIconfig``, ``gs/lib/FAPIconfig-FCO``. which may be customized by the user. The last ones defines the configuration for handling resident UFST fonts only. + +In special cases you may need to customize the file ``lib/xlatmap``. Follow instructions in it. + +Some UFST font collections need a path for finding an UFST plugin. If you run UFST with such font collection, you should run Ghostscript with a special command line argument ``-sUFST_PlugIn=path``, where path specifies a disk path to the UFST plugin file, which Monotype Imaging distributes in ``ufst/fontdata/MTFONTS/PCL45/MT3/plug__xi.fco``. If UFST needs it and the command line argument is not specified, Ghostscript prints a warning and searches plugin file in the current directory. + +If you want to run UFST with resident UFST fonts only (and allow Ghostscript font renderer to handle fonts, which may be downloaded or embedded into documents), you should run Ghostscript with these command line arguments : ``-sFCOfontfile=path1 -sFCOfontfile2=path2 -sUFST_PlugIn=path3 -sFAPIfontmap=map-name -sFAPIconfig=FAPIconfig-FCO`` where ``path1`` specifies a disk path to the main FCO file, ``path2`` specifies a disk path to the Wingdings FCO file, ``path3`` a disk path the FCO plugin file, ``path1`` is either ``gs/lib/FCOfontmap-PCLPS2``, ``gs/lib/FCOfontmap-PCLPS3``, or ``gs/lib/FCOfontmap-PS3``. ``FAPIcidfmap`` works as usual, but probably you want to leave it empty because FCO doesn't emulate CID fonts. + +Some configurations of UFST need a path for finding symbol set files. If you compiled UFST with such configuration, you should run Ghostscript with a special command line argument ``-sUFST_SSdir=path``, where path specifies a disk path to the UFST support directory, which Monotype Imaging distributes in ``ufst/fontdata/SUPPORT``. If UFST needs it and the command line argument is not specified, Ghostscript prints a warning and searches symbol set files in the current directory. + +.. note:: + + UFST and Free Type cannot handle some Ghostscript fonts because they do not include a PostScript interpreter and therefore have stronger restrictions on font formats than Ghostscript itself does - in particular, Type 3 fonts. If their font types are listed in ``HookDiskFonts`` or in ``HookEmbeddedFonts``, Ghostscript interprets them as PS files, then serializes font data into a RAM buffer and passes it to FAPI as PCLEOs. (see the FAPI-related source code for details). + + + + +.. external links + +.. _URW++ Design and Development Incorporated: http://www.urwpp.de/ + +.. include:: footer.rst + + diff --git a/doc/src/GPDL.rst b/doc/src/GPDL.rst new file mode 100644 index 00000000..991660ca --- /dev/null +++ b/doc/src/GPDL.rst @@ -0,0 +1,448 @@ +.. title:: The GhostPDL Interpreter Framework + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _GPDL.htm: + + +The GhostPDL Interpreter Framework +===================================================================== + + + + + +What is the GhostPDL Interpreter Framework? +--------------------------------------------- + +The GhostPDL interpreter framework (henceforth, just GhostPDL) is a framework into which multiple interpreters can be fitted, together with a set of interpreters for different input "languages". + +The intent is that a build of GPDL will behave as much as possible like a build of Ghostscript, but should be able to transparently cope with as many different input formats as it has interpreters built into it. + +It can be built as a dynamic link library (DLL) on Microsoft Windows, as a shared object on the Linux, Unix and MacOS X platforms. With some changes, it could be built as a static library. + +The reason we dub it a "Framework" is that it is designed to be modular, and to readily allow new interpreters to be swapped in and out to extend and customise its capabilities. + +Jobs must be separated by UEL (Universal End of Language) code sequences (or PJL fragments, which implicitly start with a ``UEL`` marker). + + + +The API +--------------------------------------------- + +The API for GPDL (found in ``plapi.h``) is deliberately designed to be nearly identical to that for Ghostscript itself (found in ``iapi.h``). Details of Ghostscript's API can be found :ref:`here<API.htm>`, and we refer you to that. Only differences from that API will be documented here. In particular the differences in the handling of switches within the ``gsapi_init_with_args`` are documented here. + +Our intent is that existing users of the Ghostscript API should be able to drop a GPDL DLL in as a replacement with little to no code changes. + + + +The run_string APIs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``run_string`` APIs have parameters for int ``user_errors`` and int ``*error_code``. Within Ghostscript, these allow a caller to bypass the language's standard error handling, and to trap errors externally. This makes no sense within a printer implementation (and, in particular, no sense for a postscript interpreter running jobs within a JobServer loop as GPDL does). Thus these parameters are kept for ABI compatibility, but are largely ignored within the GPDL implementation of gsapi. For sanity, pass 0 for ``user_errors``, and expect ``*error_code`` to be set to 0 on exit. + +String vs File functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some file types, such as Postscript and PCL, are designed to be 'streamable'; that is to say that the files can be fed in and consumed as they are interpreted. Other file types, such as PDF or XPS require the whole file to be available so that the interpreters can seek back and forth within it to extract the data they require. + +Traditionally, Ghostscript has relied upon the caller knowing which type of data is which; streamable data can be fed in to the system using the ``gsapi_run_string`` APIs, and complete files of data can be fed in using ``gsapi_run_file`` or ``gsapi_init_with_args`` APIs. Streamable data contained with a file is simple to deal with, as it's trivial for an interpreter to read bytes from a file, but doing random access on a stream is much harder. + +In systems where data is being streamed in, but it is required to be available for random access, the entire stream must be buffered for presentation to the language interpreters. With Ghostscript, the responsibility for doing this fell to the caller. Unfortunately, this means that the caller also has to be responsible for scanning the incoming data to spot when it is in a format that requires buffering. With the explosion of formats that GPDL supports this quickly becomes unpalatable. + +While the caller is still free to do such buffering of data itself, GPDL will do it automatically if required. If a language spots that data being fed to it via the ``gsapi_run_string`` APIs is in a format that requires buffering, the entire string of data will be automatically collected together, and then be represented internally to the ``gsapi_run_file`` API. + +The current implementation buffers the data in memory. Alternative implementations could use a backing store if such a thing were available. For server based applications the use of memory is not likely to be a problem (assuming reasonably sized input files at least). For printer integrations, it's entirely possible that no backing store will be available, so RAM may be the only option. Integrators may wish to place a limit on the size of files that can be buffered in this way. + + + +The GPDL executable +------------------------------------ + +The GPDL executable is a small executable that loads the DLL/shared object, and implements, pretty much, the interface described in the :ref:`usage documentation<Use.htm>` for Ghostscript, but capable of reading any of the configured languages. This executable provides all the interaction with the windowing system, including image windows. + +Areas where the GPDL executable differs from the Ghostscript executable are described :ref:`below<Differences in switches from Ghostscript>`. These are primarily to do with (slightly) esoteric requirements when running Postscript in an interactive environment. Whereas Ghostscript is a generic Postscript interpreter, GPDL is unashamedly targeted as a print processor. + +The GPDL framework's library name and characteristics differ for each platform: + +- The Win32 DLL ``gpdldll32.dll`` can be used by multiple programs simultaneously, but only once within each process. +- The Linux shared object ``libgs.so`` can be used by multiple programs simultaneously. + +The source for the executable is in ``plw*.*`` (Windows) and ``plx*.*`` (Linux/Unix). See these source files for examples of how to use the DLL. + +At this stage, GhostPDL does not support multiple instances of the interpreter within a single process. + + + +Differences in switches from Ghostscript +------------------------------------------------------------------------ + +The ``gsapi_init_with_args`` API entrypoint takes a set of arguments, which can include various switches. We document the differences between Ghostscript's handling of switches and GhostPDL's here. The GhostPDL executable directly maps parameters given on the command-line into this list, so this list of differences applies both to API calls and uses of the executable. + +GhostPDL does not support the ``-_``, ``-+``, ``-@``, ``-B``, ``-F``, ``-M``, ``-N``, ``-P``, ``-u``, and ``-X`` switches that Ghostscript does. + +GhostPDL supports a few switches that the Ghostscript executable does not. + +- ``-E #``: Sets the "error reporting mode" for PCL/PXL. +- ``-H #x#x#x#``: Sets the hardware margins to the given left/bottom/right/top values (in points). +- ``-j <string>``: Passes the string to the PJL level. The string is split on '``;``'. +- ``-J``: Same as ``-j``. +- ``-l {RTL,PCL5E,PCL5C}``: Sets the "personality" of the PCL/PXL interpreter. +- ``-L <language>``: Sets the language to be used. Run with -L and no string to see a list of languages supported in your build. +- ``-m #x#``: Sets the margin values to the left/bottom values (in points). + + +Supported languages +------------------------------------------------------------------------ + +The following is a (possibly non-exhaustive) list of languages for which implementations exist for GhostPDL. We use the term "language" to include both full page description languages (such as PCL, Postscript and XPS), and handlers for simpler formats (such as JPEG, PNG and TIFF). + +It is inherent in the design that new handlers can be included, and unwanted formats can be dropped from any given build/integration. + +PJL +~~~~~~~~~~~~~~ + +PJL is special, in that it is the central language implementation to which we return between all jobs. As such it always appears first in the list, and must be present in all builds. + +PCL +~~~~~~~~~~~~~~ + +The PCL language implementation supports PCL5C/PXL5E and HPGL/2 with RTL. + +PCLXL +~~~~~~~~~~~~~~ + +The PCLXL language implementation supports PCLXL. + +XPS +~~~~~~~~~~~~~~ + +The XPS language implementation supports the XML Paper Specification format, as used in modern Windows systems printing pipelines. + +POSTSCRIPT +~~~~~~~~~~~~~~ + +The POSTSCRIPT language implementation is the Ghostscript Postscript interpreter, as described in the accompanying documentation. + +URF +~~~~~~~~~~~~~~ + +Currently available to commercial customers only, the URF language implementation implements support for the URF file format, as used by Apple Airprint. + +JPG +~~~~~~~~~~~~~~ + +The JPG language implementation supports JPEG files (in both JFIF and EXIF formats). + +PWG +~~~~~~~~~~~~~~ + +The PWG language implementation supports PWG (Printer Working Group) format files. + +TIFF +~~~~~~~~~~~~~~ + +The TIFF language implementation supports TIFF format files in a variety of compression formats, depending on the exact configuration of libtiff used in the build. + +JBIG2 +~~~~~~~~~~~~~~ + +The JBIG2 language implementation supports JBIG2 format images. + +JP2K +~~~~~~~~~~~~~~ + +The JP2K language implementation supports JPEG2000 and JPX format images. + +PNG +~~~~~~~~~~~~~~ + +The PNG language implementation supports PNG format images. + + + +Adding a new language +-------------------------------- + +Each language implementation in the system appears as an instance of a ``pl_interp_implementation_t`` structure. + + +.. code-block:: c + + typedef struct pl_interp_implementation_s + { + /* Procedure vector */ + pl_interp_proc_characteristics_t proc_characteristics; + pl_interp_proc_allocate_interp_instance_t proc_allocate_interp_instance; + pl_interp_proc_get_device_memory_t proc_get_device_memory; + pl_interp_proc_set_param_t proc_set_param; + pl_interp_proc_add_path_t proc_add_path; + pl_interp_proc_post_args_init_t proc_post_args_init; + pl_interp_proc_init_job_t proc_init_job; + pl_interp_proc_run_prefix_commands_t proc_run_prefix_commands; + pl_interp_proc_process_file_t proc_process_file; + pl_interp_proc_process_begin_t proc_process_begin; + pl_interp_proc_process_t proc_process; + pl_interp_proc_process_end_t proc_process_end; + pl_interp_proc_flush_to_eoj_t proc_flush_to_eoj; + pl_interp_proc_process_eof_t proc_process_eof; + pl_interp_proc_report_errors_t proc_report_errors; + pl_interp_proc_dnit_job_t proc_dnit_job; + pl_interp_proc_deallocate_interp_instance_t + proc_deallocate_interp_instance; + void *interp_client_data; + } pl_interp_implementation_t; + +This structure consists of series of function pointers, each of which performs some portion of the processing required to handle detection of language type and processing of data. These function pointers are described in detail below. + +In addition, the ``interp_client_data`` field is used to hold the running state of a given interpreter. + +All the languages to be supported in the build are listed in the ``pdl_implementations`` array in ``plimpl.c``. To add a new implementation the name of the appropriate ``pl_interp_implementation_t`` should be added here. + +The existing range of language implementations may prove useful as references when implementing new ones. They can be found as ``gpdl/*top.c``. In particular, ``pngtop.c`` is a simple implementation of a well-defined, relatively simple file format (PNG), based upon a well-known and well-documented library (``libpng``), so is probably a good place to start. + + +proc_characteristics +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef const pl_interp_characteristics_t + *(*pl_interp_proc_characteristics_t) (const pl_interp_implementation_t *); + + +This entrypoint is called to request details of the characteristics of the language. This must be implemented in all instances. + +This returns a pointer to a ``pl_interp_characteristics_t`` structure: + + +.. code-block:: c + + typedef struct pl_interp_characteristics_s + { + const char *language; /* generic language should correspond with + HP documented PJL name */ + int (*auto_sense)(const char *string, int length); /* routine used to detect language - returns a score: 0 is definitely not, 100 is definitely yes. */ + const char *manufacturer; /* manuf str */ + const char *version; /* version str */ + const char *build_date; /* build date str */ + } pl_interp_characteristics_t; + + +The language entry contains a simple NULL terminated string that names the interpreter. Similarly, the manufacturer, version, and ``build_date`` fields are for informational purposes only. + +The ``auto_sense`` function is called with a prefix of data from each new source. Each language is passed the data in turn, and "scores;" according to how sure it is the file is that format. + +For many file formats this means looking for known in the first few bytes (such as PNG or TIFF looking for their signature bytes). For others, such as XPS, the best that can be done is to spot that it's a zip file. For still others, such as PCL, heuristics have to be used. + +A 'definite' match is returned as 100, a definite rejection as 0, with intermediate values used appropriately. + + +proc_allocate_interp_instance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_allocate_interp_instance_t) + (pl_interp_implementation_t *, + gs_memory_t *); + +On startup, the GPDL library calls around all the languages via this function, getting them to allocate themselves an instance. What this means will vary between languages, but typically it involves allocating a state structure, and storing the pointer to that in the ``interp_client_data`` pointer of the ``pl_interp_implementation_t *``. Part of this state structure will typically be a ``gstate`` to use to drive the graphics library. + +proc_get_device_memory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef gs_memory_t *(*pl_interp_proc_get_device_memory_t) + (pl_interp_implementation_t *); + + +On shutdown, the GPDL library calls around all the languages via this function, getting them to release their resources and deallocate any memory. + + +proc_set_param +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_set_param_t) (pl_interp_implementation_t *, + pl_set_param_type, + const char *, + const void *); + +Some languages (particularly Postscript) can have their behaviour changed by the use of parameters. This function provides a generic method for the GPDL library to pass parameters into a language. Each language is free to ignore the parameters that do not apply to it. For most languages, this can safely be passed as NULL. + +proc_add_path +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + typedef int (*pl_interp_proc_add_path_t) (pl_interp_implementation_t *, + const char *); + +Some languages (particularly Postscript) have the ability to open files from the local storage. These files can be found in a variety of different locations within the local storage. As such this call allows the GPDL library to add paths to the current list of locations that will be searched. For most languages, this can safely be passed as NULL. + + +proc_post_args_init +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_post_args_init_t) (pl_interp_implementation_t *); + + + +proc_init_job +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + typedef int (*pl_interp_proc_init_job_t) (pl_interp_implementation_t *, + gx_device *); + +Once the GPDL library has identified which language should be used for an incoming job, it will call this entrypoint to initialise the language for the job. What this means will vary between languages, but at the very minimum the job will need to take note of the device to be used. + +proc_run_prefix_commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_run_prefix_commands_t) + (pl_interp_implementation_t *, + const char *prefix); + +The GPDL library (and executable) allow language commands to be sent in the argument parameters using the ``-c`` switch. These are collected into a buffer, and forwarded to a language to be run as part of the same job as any following file. + +Currently, only the Postscript language handler implements this function, all others should pass NULL. + + +proc_process_file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_process_file_t) (pl_interp_implementation_t *, + const char *); + +If the GPDL library is given a filename to process, and this function is non-NULL, it will call this to run the file. For file formats such as PDF (which need to be buffered so they can be read out of order), this can avoid the need to feed in all the data via ``proc_process``, buffer it somewhere, and then process it at the end. + +For many languages this can be NULL. + +proc_process_begin +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + typedef int (*pl_interp_proc_process_begin_t) (pl_interp_implementation_t *); + +Once the GPDL library has data to process (that it cannot process with ``proc_process_file``, it will call this function to setup the transfer of data. + + +proc_process +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_process_t) (pl_interp_implementation_t *, + stream_cursor_read *); + +After the GPDL library has called ``proc_process_begin`` this function may be called multiple times to actually transfer the data in. The implementation is expected to consume as many bytes as it can (but not necessarily all of them) before returning with an updated read pointer. If this function cannot advance without more data, it should return with ``gs_error_NeedInput``. + +proc_process_end +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_process_end_t) (pl_interp_implementation_t *); + +After the GPDL library has called ``proc_process_begin`` (and possibly made a number of calls to ``proc_process``) it will call ``proc_process_end`` to signify the end of the data. This does not necessarily signal the end of the job. + +proc_flush_to_eoj +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + typedef int (*pl_interp_proc_flush_to_eoj_t) (pl_interp_implementation_t *, + stream_cursor_read *); + +In the event of a problem while processing data, GPDL may seek to abandon processing of a transfer in progress by calling ``proc_flush_to_eoj``. If possible, the language should continue to process data until a reasonable stopping point, or until UEL is reached. + + +proc_process_eof +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + typedef int (*pl_interp_proc_process_eof_t) (pl_interp_implementation_t *); + + +Called when GPDL reaches EOF in processing a job. A language implementation should assume no more data is forthcoming. + +proc_report_errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_report_errors_t) (pl_interp_implementation_t *, + int, + long, + bool); + +Called after running a job to give the language implementation the chance to report any errors it may have detected as it ran. + +proc_dnit_job +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + typedef int (*pl_interp_proc_dnit_job_t) (pl_interp_implementation_t *); + +Called after a job is complete so that the language implementation may clean up. The interpreter is kept open so that more jobs can be fed to it, but no state should be kept from this job to the next. + + +proc_deallocate_interp_instance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: c + + typedef int (*pl_interp_proc_deallocate_interp_instance_t) + (pl_interp_implementation_t *); + +Called on shutdown of the GPDL library to close down the language instance and free all the resources. + + + + + + + + + + + + + + + + + + + + + +.. include:: footer.rst diff --git a/doc/src/Install.rst b/doc/src/Install.rst new file mode 100644 index 00000000..2141d703 --- /dev/null +++ b/doc/src/Install.rst @@ -0,0 +1,274 @@ +.. title:: How to Install Ghostscript + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Install.htm: +.. _HowToInstallGhostscript: + + +How to Install Ghostscript +=================================== + + + + +Overview of how to install Ghostscript +---------------------------------------- + +You must have four things to run Ghostscript: + +#. The Ghostscript executable file; on some operating systems, more than one file is required. These are entirely platform-specific. See below for details. + +#. Initialization files that Ghostscript reads in when it starts up; these are the same on all platforms. + +#. + + - ``gs_*.ps`` unless Ghostscript was compiled using the "compiled initialization files" option. See the documentation of :ref:`PostScript files distributed with Ghostscript<PsFiles.htm>`. + + - ``pdf_*.ps`` if Ghostscript was compiled with the ability to interpret Adobe Portable Document Format (PDF) files, that is, ``pdf.dev`` was included in ``FEATURE_DEVS`` when Ghostscript was built. + + - ``Fontmap`` and ``Fontmap.GS`` (or the appropriate ``Fontmap.xxx`` for your platform), unless you plan always to invoke Ghostscript with the :ref:`-dNOFONTMAP switch<UseDNoFontMap>`. + +#. Fonts, for rendering text. These are platform-independent, but if you already have fonts of the right kind on your platform, you may be able to use those. See below for details. Also see the :ref:`documentation on fonts<Fonts.htm>`. + + +The :ref:`usage documentation<Use.htm>` describes the search algorithms used to find initialization files and font files. The per-platform descriptions that follow tell you where to install these files. + + + +Installing Ghostscript on Unix +---------------------------------------- + +Ghostscript uses the common ``configure``, ``build`` and ``install`` method common to many modern software packages. In general the following with suffice to build Ghostscript: + + +.. code-block:: bash + + ./configure + make + + +and then it may be installed in the default location with: + +.. code-block:: bash + + make install + + +This last command may need to be performed with super user privileges. + +You can set the installation directory by adding ``--prefix=path`` to the configure invocation in the first step. The default prefix is ``/usr/local``, which is to say the ``gs`` executable is installed as ``/usr/local/bin/gs``. + +A list of similar configuration options is available via ``./configure --help``. + +For more detailed information on building Ghostscript see :ref:`how to build Ghostscript on Unix<MakeHowToBuildForUnix>` in the documentation on building Ghostscript, especially regarding information on using the older hand edited ``makefile`` approach. Whatever configuration method you use, execute ``make install`` to install the executable and all the required and ancillary files after the build is complete. + + + +Fonts +~~~~~~~~~~~~~~~~~~~ + +The ``makefile`` installs all the files except fonts under the directory defined in the ``makefile`` as prefix. Fonts need to be installed separately. The fonts should be installed in ``{prefix}/share/ghostscript/fonts``. (That is, ``/usr/local/share/ghostscript/fonts/`` if you used the default configuration above.) + +If you have Adobe Acrobat installed, you can use the Acrobat fonts in place of the ones distributed with with Ghostscript by adding the Acrobat fonts directory to ``GS_FONTPATH`` and removing these fonts from ``Fontmap.GS``: + ``Courier``, ``Courier-Bold``, ``Courier-BoldOblique``, ``Courier-Oblique``, ``Helvetica``, ``Helvetica-Bold``, ``Helvetica-BoldOblique``, ``Helvetica-Oblique``, ``Symbol``, ``Times-Bold``, ``Times-BoldItalic``, ``Times-Italic``, ``Times-Roman``, ``ZapfDingbats`` + + + +Similarly, you can have Ghostscript use other fonts on your system by adding entries to the ``fontmap`` or adding the directories to the ``GS_FONTMAP`` environment variable. See the :ref:`usage documentation<Use.htm>` for more information. + +For example, many linux distributions place fonts under ``/usr/share/fonts``. + + +Ghostscript as a shared object +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you've built Ghostscript as a shared object, instead of ``make install``, you must use ``make soinstall``. See :ref:`how to build Ghostscript as a shared object<Make_SharedObject>` for more details. + + +Additional notes on Linux +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For Linux, you may be able to install or upgrade Ghostscript from precompiled RPM_ files using: + + +.. code-block:: bash + + rpm -U ghostscript-N.NN-1.i386.rpm + rpm -U ghostscript-fonts-N.NN-1.noarch.rpm + + +However, please note that we do not create RPMs for Ghostscript, and we take no responsibility for RPMs created by others. + + + +Installing Ghostscript on MS Windows +---------------------------------------- + + +We usually distribute Ghostscript releases for Windows as a binary installer, for the convenience of most users. + +Windows 3.1 (16-bit) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The last version to run on 16-bit Windows 3.1 was Ghostscript 4.03. + +Windows 95, 98, Me +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The last version to be available as a binary for Windows 95/98/Me was 8.60. Although building from source with Visual Studio 2003 should produce a working binary for those versions. + +Windows NT4, 2000, XP, 2003 or Vista (32-bit) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The installer is normally named ``gs###w32.exe``, where ``###`` is the release number (e.g., 871 for Ghostscript 8.71, 910 for Ghostscript 9.10). + +Windows XP x64 edition, 2003 or Vista (64-bit) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The x64 installer is normally named ``gs###w64.exe`` This is for 64-bit Windows operating systems based on the x64 instruction set. Do not use this on 64-bit processors running 32-bit Windows. + +Installing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To install Ghostscript on Windows, you should run the installer executable. + +The installer is NSIS-based and supports a few standard NSIS options: ``/NCRC`` disables the ``CRC`` check, ``/S`` runs the installer or uninstaller silently, ``/D`` sets the default installation directory (It must be the last parameter used in the command line and must not contain any quotes, even if the path contains spaces. Only absolute paths are supported). + + +General Windows configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The installer includes files in these subdirectories: + +- ``gs#.##\bin`` +- ``gs#.##\examples`` +- ``gs#.##\lib`` +- ``gs#.##\doc`` +- ``gs#.##\Resource`` +- ``fonts`` + + +The actual executable files for the 32-bit Windows install, in the ``gs#.##\bin`` subdirectory, are: + + +.. list-table:: + :widths: 20 80 + :header-rows: 0 + + * - GSWIN32C.EXE + - Ghostscript as a 32-bit Windows command line program. This is usually the preferred executable. + * - GSWIN32.EXE + - 32-bit Ghostscript using its own window for commands. + * - GSDLL32.DLL + - 32-bit dynamic link library containing most of Ghostscript's functionality. + + +For the 64-bit Windows install, also in the ``gs#.##\bin`` subdirectory, they are: + + +.. list-table:: + :widths: 20 80 + :header-rows: 0 + + * - GSWIN64C.EXE + - Ghostscript as a 64-bit Windows command line program. This is usually the preferred executable. + * - GSWIN64.EXE + - 64-bit Ghostscript using its own window for commands. + * - GSDLL64.DLL + - 64-bit dynamic link library containing most of Ghostscript's functionality. + + +For printer devices, the default output is the default printer. This can be modified as follows: + +.. code-block:: bash + + -sOutputFile="%printer%printer name" + +If your printer is named "HP DeskJet 500" then you would use ``-sOutputFile="%printer%HP DeskJet 500"``. + + + +If Ghostscript fails to find an environment variable, it looks for a registry value of the same name under the key + +.. code-block:: bash + + HKEY_CURRENT_USER\Software\GPL Ghostscript\#.## + +or if that fails, under the key: + +.. code-block:: bash + + HKEY_LOCAL_MACHINE\SOFTWARE\GPL Ghostscript\#.## + +where ``#.##`` is the Ghostscript version number. + +Ghostscript will attempt to load the Ghostscript dynamic link library ``GSDLL32.DLL`` in the following order: + + +- In the same directory as the Ghostscript executable. + +- If the environment variable ``GS_DLL`` is defined, Ghostscript tries to load the Ghostscript dynamic link library (``DLL``) with the name given. + +- Using the standard Windows library search method: the directory from which the application loaded, the current directory, the Windows system directory, the Windows directory and the directories listed in the ``PATH`` environment variable. + + +The Ghostscript installer will create registry values for the environment variables ``GS_LIB`` and ``GS_DLL``. + + +Uninstalling Ghostscript on Windows +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To uninstall Ghostscript, use the Control Panel, Add/Remove Programs and remove "Ghostscript #.##" and "Ghostscript Fonts". (The entries may be called "GPL Ghostscript" or "AFPL Ghostscript", rather than just "Ghostscript", depending on what version of Ghostscript was installed). + +Alternatively, an uninstall shortcut is also available in the Start Menu group. + + + + +Installing Ghostscript on OpenVMS +------------------------------------------- + +Support for OpenVMS has stagnated (and almost certainly bit-rotted), and as the core development team has no access to an OpenVMS environment, we are unable to bring it up to date. We will consider patches from contributors if any wish to take on the task of getting it working again. Given the very limited appeal of OpenVMS these days, however, we are unlikely to consider patches with invasive code changes. + +You need the file ``GS.EXE`` to run Ghostscript on OpenVMS, and installing Ghostscript on an OpenVMS system requires building it first. + +The following installation steps assume that the Ghostscript directory is ``DISK1:[DIR.GHOSTSCRIPT]``. Yours will almost certainly be in a different location so adjust the following commands accordingly. + +- Download the fonts and unpack them into ``DISK1:[DIR.GHOSTSCRIPT.LIB]``. + +- Enable access to the program and support files for all users with: + + .. code-block:: bash + + $ set file/prot=w:re DISK1:[DIR]GHOSTSCRIPT.dir + $ set file/prot=w:re DISK1:[DIR.GHOSTSCRIPT...]*.* + +- Optionally, add the Ghostscript help instructions to your system wide help file: + + .. code-block:: bash + + $ lib/help sys$help:HELPLIB.HLB DISK1:[DIR.GHOSTSCRIPT.DOC]GS-VMS.HLP + +- Lastly, add the following lines to the appropriate system wide or user specific login script. + + .. code-block:: bash + + $ define gs_exe DISK1:[DIR.GHOSTSCRIPT.BIN] + $ define gs_lib DISK1:[DIR.GHOSTSCRIPT.EXE] + $ gs :== $gs_exe:gs.exe + +If you have ``DECWindows/Motif`` installed, you may wish to replace the ``FONTMAP.GS`` file with ``FONTMAP.VMS``. Read the comment at the beginning of the latter file for more information. + + + +.. External links + +.. _RPM: http://www.rpm.org/ + + +.. include:: footer.rst + diff --git a/doc/src/Language.rst b/doc/src/Language.rst new file mode 100644 index 00000000..5a777849 --- /dev/null +++ b/doc/src/Language.rst @@ -0,0 +1,1284 @@ +.. title:: Ghostscript and the PostScript Language + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Language.htm: +.. _Language: + + +Ghostscript and the PostScript Language +=========================================== + + + +Ghostscript's capabilities in relation to PostScript +--------------------------------------------------------- + +The Ghostscript interpreter, except as noted below, is intended to execute properly any source program written in the (LanguageLevel 3) PostScript language as defined in the PostScript Language Reference, Third Edition (ISBN 0-201-37922-8) published by Addison-Wesley in mid-1999. However, the interpreter is configurable in ways that can restrict it to various subsets of this language. Specifically, the base interpreter accepts the Level 1 subset of the PostScript language, as defined in the first edition of the PostScript Language Reference Manual (ISBN 0-201-10174-2) Addison-Wesley 1985, plus the file system, version 25.0 language, and miscellaneous additions listed in sections A.1.6, A.1.7, and A.1.8 of the Second Edition respectively, including allowing a string operand for the "``status``" operator. The base interpreter may be configured (see the documentation on :ref:`building Ghostscript<Make.htm>` for how to configure it) by adding any combination of the following: + +- The ability to process PostScript Type 1 fonts. This facility is normally included in the interpreter. + +- The CMYK color extensions listed in section A.1.4 of the Second Edition (including ``colorimage``). These facilities are available only if the ``color``, ``dps``, or ``level2`` feature was selected when Ghostscript was built. + +- The Display PostScript extensions listed in section A.1.3 of the Second Edition, but excluding the operators listed in section A.1.2. These facilities are available only if the dps feature or the ``level2`` feature was selected when Ghostscript was built. + +- The composite font extensions listed in section A.1.5 of the Second Edition, and the ability to handle Type 0 fonts. These facilities are available only if the compfont feature or the ``level2`` feature was selected when Ghostscript was built. + +- The ability to load TrueType fonts and to handle PostScript Type 42 (encapsulated TrueType) fonts. These facilities are available only if the ``ttfont`` feature was selected when Ghostscript was built. + +- The PostScript Level 2 "filter" facilities except the ``DCTEncode`` and ``DCTDecode`` filters. These facilities are available only if the ``filter``, ``dps``, or ``level2`` feature was selected when Ghostscript was built. + +- The PostScript Level 2 ``DCTEncode`` and ``DCTDecode`` filters. These facilities are available only if the ``dct`` or ``level2`` feature was selected when Ghostscript was built. + +- All the other PostScript Level 2 operators and facilities listed in section A.1.1 of the Second Edition and not listed in any of the other A.1.n sections. These facilities are available only if the ``level2`` feature was selected when Ghostscript was built. + +- All PostScript LanguageLevel 3 operators and facilities listed in the Third Edition, except as noted below. These facilities are available only if the ``psl3`` feature was selected when Ghostscript was built. + +- The ability to recognize DOS EPSF files and process only the PostScript part, ignoring bitmap previews or other information. This facility is available only if the ``epsf`` feature was selected when Ghostscript was built. + + +Ghostscript currently does not implement the following PostScript LanguageLevel 3 facilities: + +- Settable ``ProcessColorModel`` for page devices, except for a very few special devices. + +- ``IODevices`` other than ``%stdin``, ``%stdout``, ``%stderr``, ``%lineedit``, ``%statementedit``, ``%os%``, and (if configured) ``%pipe%`` and ``%disk0%`` through ``%disk0%``. + + +Ghostscript can also interpret files in the Portable Document Format (PDF) 1.7 format defined in the PDF Reference Version 1.7, distributed by Adobe Systems Incorporated, except as noted below. This facility can be disabled by deselecting the pdf feature when Ghostscript is built. + +Ghostscript currently implements the majority of non-interactive features defined in the PDF reference. + +Ghostscript also includes a number of :ref:`additional operators<Additional Operators>` defined below that are not in the PostScript language defined by Adobe. + + +Implementation limits +--------------------------- + +The implementation limits show here correspond to those in Tables B.1 and B.2 of the Second and Third Editions, which describe the quantities fully. Where Ghostscript's limits are different from those of Adobe's implementations (as shown in the Third Edition), Adobe's limits are also shown. + + +Architectural limits +~~~~~~~~~~~~~~~~~~~~ + +*Architectural limits (corresponds to Adobe table B.1)* + + + +.. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Quantity + - Limit + - Type + - Adobe + * - integer + - 32-bit + - twos complement integer + - + * - real + - single-precision + - IEEE float + - + * - array + - 16777216 + - elements + - 65535 + * - dictionary + - 16777215 + - elements + - 65535 + * - string + - 16777216 + - characters + - 65535 + * - name + - 16383 + - characters + - 127 + * - filename + - 128 :ref:`*<AdobeTableNote1>` + - characters + - + * - ``save`` level + - none + - (capacity of memory) + - 15 + * - ``gsave`` level + - none + - (capacity of memory) + - 13 + +.. _AdobeTableNote1: + +\* The limit on the length of a file name is 128 characters if the name starts with a ``%...% IODevice`` designation, or 124 characters if it does not. + + +Typical memory limits in LanguageLevel 1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*Memory limits (corresponds to Adobe table B.2)* + + +.. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Quantity + - Limit + - Type + - Adobe + * - ``userdict`` + - 200 + - + - + * - ``FontDirectory`` + - 100 + - + - + * - operand stack + - 800 + - + - 500 + * - dictionary stack + - 20 + - + - + * - execution stack + - 250 + - + - + * - interpreter level + - none + - (capacity of memory) + - 10 + * - path + - none + - (capacity of memory) + - 1500 + * - dash + - 11 + - + - + * - VM + - none + - (capacity of memory) + - 240000 + * - file + - none + - (determined by operating system) + - 6 + * - image + - 65535 + - values (samples × components) + + for 1-, 2-, 4-, or 8-bit samples + - 3300 + * - + - 32767 + - values for 12-bit samples + - 3300 + + +Other differences in VM consumption +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In 32-bit builds packed array elements occupy either 2 bytes or 12 bytes. The average element size is probably about 7 bytes. Names occupy 16 bytes plus the space for the string. + +In 64-bit builds packed array elements occupy either 2 bytes or 16 bytes. The average element size is probably about 9 bytes. Names occupy 24 bytes plus the space for the string. + +The garbage collector doesn't reclaim portions of arrays obtained with getinterval, rather it collects entire arrays. + + + +.. _Additional Operators: + + +Additional operators in Ghostscript +------------------------------------- + +Graphics and text operators +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. _Language_Transparency: + +Transparency +""""""""""""""" + +.. note:: + + The following paragraphs describe non-standard operators for accessing the PDF 1.4 and later transparent imaging model through Postscript. If used incorrectly, they can have unexpected side effects and result in undefined behavior. As a result, these operators are disabled when :ref:`SAFER<dSAFER>` is in force (as it is by default from version 9.50 onwards). To utilise these operators you will either have to disable ``SAFER`` (``-dNOSAFER``) or use the command line parameter ``-dALLOWPSTRANSPARENCY``. The latter will make the custom operators available, but leave the file access controls active. + +Ghostscript provides a set of operators for implementing the transparency and compositing facilities of PDF 1.4. These are defined only if the ``transpar`` option was selected when Ghostscript was built. We do not attempt to explain the underlying graphics model here: for details, see Adobe Technical Note #5407, "Transparency in PDF". Previously (in 9.52 and earlier), Ghostscript's model maintained separate alpha and mask values for opacity and shape. This model has been changed (as of 9.53) and instead Ghostscript maintains separate float values for stroke and fill alpha values with a boolean that indicates if these should be interpreted as shape or alpha values to be more in line with the PDF specification. + +What follows is a subset of all the custom operators related to transparency, but covers the most useful, most common requirements. + +Graphics state operators +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Pushing the compositor device must be done before any other marking operations are made on the current page, and must be done per page. Popping the compositor should be done after the last marking operation of the page, and before the call to ``showpage``. Any marking operations made after the compositor is popped will bypass the transparent imaging model, and may produce unexpected output. + + +``<depth> .pushpdf14devicefilter -`` + Installs the transparency compositor device into the graphics state. At present the ``depth`` parameter should always be zero (Subject To Change.) + +``- .popdf14devicefilter -`` + Removes (or, more accuracately, disables) the transparency compositor in graphics state. + +``<modename> .setblendmode -`` + Sets the blending mode in the graphics state. If the mode name is not recognized, causes a ``rangecheck`` error. The initial value of the blending mode is ``/Compatible``. + +``- .currentblendmode <modename>`` + Returns the graphics state blend mode on the stack. + +``[Deprecated as of 9.53] <0..1> .setopacityalpha -`` + Sets the opacity alpha value in the graphics state. The initial opacity alpha value is 1. Note, it is strongly suggested that this method not be used as it currently may give inconsistent results when mixed with methods that set stroke and fill alpha values. + +``[Deprecated as of 9.53] - .currentopacityalpha <0..1>`` + Returns the graphics state opacity alpha on the stack. Note, it is strongly suggested that this method not be used as it currently may give inconsistent results when mixed with methods that set stroke and fill alpha values. + +``[Deprecated as of 9.53] <0..1> .setshapealpha -`` + Sets the shape alpha value in the graphics state. The initial shape alpha value is 1. Note, it is strongly suggested that this method not be used as it currently may give inconsistent results when mixed with methods that set stroke and fill alpha values. + +``[Deprecated as of 9.53] - .currentshapealpha <0..1>`` + Returns the graphics state shape alpha on the stack. Note, it is strongly suggested that this method not be used as it currently may give inconsistent results when mixed with methods that set stroke and fill alpha values. + +``<0..1> .setstrokeconstantalpha -`` + Sets the stroke alpha value in the graphics state. The initial stroke alpha value is 1. + +``- .currentstrokeconstantalpha <0..1>`` + Returns the graphics state stroke alpha value on the stack. + +``<0..1> .setfillconstantalpha -`` + Sets the fill alpha value in the graphics state. The initial fill alpha value is 1. + +``- .currentfillconstantalpha <0..1>`` + Returns the graphics state fill alpha value on the stack. + +``<bool> .setalphaisshape -`` + If true, the values set by ``setstrokeconstantalpha`` and ``setfillconstantalpha`` are interpreted as shape values. The initial value of the AIS flag is false. + +``- .currentalphaisshape <0..1>`` + Returns the graphics state alpha is shape (AIS) on the stack. + +``<bool> .settextknockout -`` + Sets the text knockout flag in the graphics state. The initial value of the text knockout flag is true. + +``- .currenttextknockout <bool>`` + Returns the graphics state text knockout on the stack. + + +Rendering stack operators +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The interpreter state is extended to include a (per-context) rendering stack for handling transparency groups and masks (generically, "layers"). Groups accumulate a full value for each pixel (paint plus transparency); masks accumulate only a coverage value. Layers must be properly nested, i.e., the 'end' or 'discard' operator must match the corresponding 'begin' operator. + +Beginning and ending groups must nest properly with respect to save and restore: save and restore do not save and restore the layer stack. Currently, layers are not required to nest with respect to gsave and grestore, except that the device that is current in the graphics state when ending a layer must be the same as the device that was current when beginning the layer. + + +.. warning:: THIS AREA IS SUBJECT TO CHANGE. + +``<paramdict> <llx> <lly> <urx> <ury> .begintransparencygroup -`` + Begins a new transparency group. The ``ll/ur`` coordinates are the bounding box of the group in the current user coordinate system. ``paramdict`` has the following keys: + + ``/Isolated`` + (optional) Boolean; default value = false. + + ``/Knockout`` + (optional) Boolean; default value = false. + +``- .endtransparencygroup -`` + Ends the current transparency group, compositing the group being ended onto the group that now becomes current. + +``<cs_set?> <paramdict> <llx> <lly> <urx> <ury> .begintransparencymaskgroup -`` + Begins a new transparency mask, which is represented as a group. The ``ll/ur`` coordinates are the bounding box of the mask in the current user coordinate system. ``paramdict`` has the following keys: + + ``/Subtype`` + (required) Name, either ``/Alpha`` or ``/Luminosity``. + + ``/Background`` + (optional) Array of number. + + ``/TransferFunction`` + (optional) Function object (produced by applying ``.buildfunction`` to a Function dictionary). + + The ``cs_set`` parameter is a boolean indicating whether the color space for the mask group is the current color space in the graphics state, or whether mask group color space should be inherited from the previous group in the transparency group stack. In general, for the most consistent results, it is recommended that this be set to true, and the intended color space set in the graphics state prior to the ``.begintransparencymaskgroup`` call. + +``<mask#> .endtransparencymask -`` + Ends the current transparency mask group, compositing the mask group being ended and setting it as the current soft mask in the graphics state. + The ``mask#`` parameter indicates whether the mask should be treated as as opacity mask (``0``) or shape (``1``). + + +New ImageType +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The transparency extension defines a new ImageType 103, similar to ImageType 3 with the following differences: + +- The required ``MaskDict`` is replaced by two optional dictionaries, ``OpacityMaskDict`` and ``ShapeMaskDict``. If present, these dictionaries must have a ``BitsPerComponent`` entry, whose value may be greater than 1. Note that in contrast to ImageType 3, where any non-zero chunky mask value is equivalent to 1, ImageType 103 simply takes the low-order bits of chunky mask values. + +- A ``Matte`` entry may be present in one or both mask dictionaries, indicating premultiplication of the data values. If both ``MaskDicts`` have a ``Matte`` entry and the values of the two ``Matte`` entries are different, a ``rangecheck`` error occurs. + +- ``InterleaveType`` appears in the ``MaskDicts``, not the ``DataDict``, because each mask has its own ``InterleaveType``. ``InterleaveType`` 2 (interlaced scan lines) is not supported. + + + +Other graphics state operators +""""""""""""""""""""""""""""""" + +``<int> .setoverprintmode -`` + Sets the overprint mode in the graphics state. Legal values are 0 or 1. Per the PDF 1.3 specification, if the overprint mode is 1, then when the current color space is ``DeviceCMYK``, color components whose value is 0 do not write into the target, rather than writing a 0 value. THIS BEHAVIOR IS NOT IMPLEMENTED YET. The initial value of the overprint mode is 0. + +``- .currentoverprintmode <int>`` + Returns the current overprint mode. + +Character operators +""""""""""""""""""""""""""""""" + +``<font> <charcode> %Type1BuildChar -`` + This is not a new operator: rather, it is a name known specially to the interpreter. Whenever the interpreter needs to render a character (during a ``...show``, ``stringwidth``, or ``charpath``), it looks up the name ``BuildChar`` in the font dictionary to find a procedure to run. If it does not find this name, and if the ``FontType`` is 1, the interpreter instead uses the value (looked up on the dictionary stack in the usual way) of the name ``%Type1BuildChar``. + + The standard definition of ``%Type1BuildChar`` is in the initialization file ``gs_type1.ps``. Users should not need to redefine ``%Type1BuildChar``, except perhaps for tracing or debugging. + +``<font> <charname> %Type1BuildGlyph -`` + Provides the Type 1 implementation of ``BuildGlyph``. + + +Other operators +~~~~~~~~~~~~~~~~~~~~~ + +Mathematical operators +"""""""""""""""""""""""""" + +``<number> arccos <number>`` + Computes the arc cosine of a number between -1 and 1. + +``<number> arcsin <number>`` + Computes the arc sine of a number between -1 and 1. + +Dictionary operators +"""""""""""""""""""""""""" + +``mark <key1> <value1> <key2> <value2> ... .dicttomark <dict>`` + Creates and returns a dictionary with the given keys and values. This is the same as the PostScript Level 2 >> operator, but is available even in Level 1 configurations. + +``<dict> <key> .knownget <value> true``, ``<dict> <key> .knownget false`` + Combines ``known`` and ``get`` in the obvious way. + + +File operators +"""""""""""""""""""""""""" + +``<file> .fileposition <integer> true`` + Returns the position of file. Unlike the standard ``fileposition`` operator, which causes an error if the file is not positionable, ``.fileposition`` works on all files, including filters: for non-positionable files, it returns the total number of bytes read or written since the file was opened. + +``<string> findlibfile <foundstring> <file> true``, ``<string> findlibfile <string> false`` + Opens the file of the given name for reading, searching through directories :ref:`as described in the usage documentation<Use_How Ghostscript finds files>`. If the search fails, ``findlibfile`` simply pushes false on the stack and returns, rather than causing an error. + +.. _Tempfile: + +``<prefix_string|null> <access_string> .tempfile <string> <file>`` + Creates and opens a temporary file like the file operator, also returning the file name. There are three cases for the ``<prefix_string|null>`` operand: + + - ``null``: create the file in the same directory and with the same name conventions as other temporary files created by the Ghostscript implementation on this platform. E.g., the temporary file might be named ``/tmp/gs_a1234``. + + - A string that contains only alphanumeric characters, underline, and dash: create the file in the standard temporary directory, but use the ``<prefix_string>`` as the first part of the file name. E.g., if ``<prefix_string>`` is ``xx``, the temporary file might be named ``/tmp/xxa1234``. + + - A string that is the beginning of an absolute file name: use the ``<prefix_string>`` as the first part of the file name. E.g., if ``<prefix_string>`` is ``/my/tmpdir/zz``, the temporary file might be named ``/my/tmpdir/zza1234``. + + When running in ``SAFER`` mode, the absolute path must be one of the strings on the permit file writing list (see :ref:`-dSAFER<dSAFER>`) . + + +Ghostscript also supports the following ``IODevice`` in addition to a subset of those defined in the Adobe documentation: + +- ``%pipe%command``, which opens a pipe on the given command. This is supported only on operating systems that provide popen (primarily Unix systems, and not all of those). + +- ``%disk#%``, which emulates the ``%disk0`` through ``%disk9`` devices on some Adobe PostScript printers. This pseudo device provides a flat filenaming system with a user definable location for the files (``/Root``). These devices will only be present if the ``diskn.dev`` feature is specified during the build. + + This feature is intended to allow compatibility with font downloaders that expect to store fonts on the ``%disk`` device of the printer. + + Use of the ``%disk#%`` devices requires that the location of files be given by the user setting the ``/Root`` device parameter. The syntax for setting the ``/Root`` parameter is: + + .. code-block:: postscript + + mark /Root (directory_specification) (%disk#) .putdevparams + + For example, to store the files of the ``%disk0`` device on the directory ``/tmp/disk0``, use: + + .. code-block:: postscript + + mark /Root (/tmp/disk0/) (%disk0) .putdevparams + + The files will be stored in the specified directory with arbitrary names. A mapping file is used to store the association between the file names given for the file operations on the ``%diskn#`` device and the file that resides in the ``/Root`` directory. + + +Miscellaneous operators +"""""""""""""""""""""""""" + +``<array> bind <array>`` + + Depending on the command line parameters ``bind`` is redefined as: + + + .. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Flag + - Definition + * - ``DELAYBIND`` + - Returns the argument, stores the argument for later use by ``.bindnow`` + + + +``<array> .bind <array>`` + Performs standard bind operation as defined in PLRM regardless of the ``DELAYBIND`` flag. + + +.. _Language_BindNow: + +``- .bindnow -`` + Applies ``bind`` operator to all saved procedures after binding has been deferred through ``-dDELAYBIND``. Note that idiom recognition has no effect for the deferred binding because the value returned from ``bind`` is discarded. + + Since v. 8.12 ``.bindnow`` undefines itself and restores standard definition of ``bind`` operator. In earlier versions after calling ``.bindnow``, the postscript ``bind`` operator needs to be rebound to the internal implementation ``.bind``, as in this fragment from the ``ps2ascii`` script: + + .. code-block:: postscript + + DELAYBIND { + .bindnow + /bind /.bind load def + } if + + + This is necessary for correct behavior with later code that uses the ``bind`` operator. + + +``<string> getenv <string> true``, ``<string> getenv false`` + Looks up a name in the shell environment. If the name is found, returns the corresponding value and true; if the name is not found, returns false. + +``<string> <boolean> .setdebug -`` + Sets or clears any subset of the debugging flags included in ``<string>`` based on the value of ``<boolean>``. These correspond to the debug flags set by ``-Z`` on the command line and enable debug and tracing output from various internal modules. + + .. note:: + + Most tracing output is only produced if the Ghostscript interpreter was built with the ``DEBUG`` preprocessor symbol defined. + + The ``zsetdebug()`` C function, which implements this operator, is a useful breakpoint for debuggers. Inserting '``() true .setdebug``' in the interpreted code will trigger a breakpoint at that location without side effects. The current flag state is available in C as the ``gs_debug[]`` array, indexed by character value. The ``zsetdebug`` function will be entered, and ``gs_debug[]`` updated, whether or not Ghostscript is built with the ``DEBUG`` preprocessor symbol defined, so this is useful even with release builds. + + +``- .setsafe -`` + If Ghostscript is started with ``-dNOSAFER`` or ``-dDELAYSAFER``, this operator can be used to enter ``SAFER`` mode (see :ref:`-dSAFER<dSAFER>`) + + The following is deprecated, see :ref:`-dSAFER<dSAFER>`. + + Since ``SAFER`` mode is implemented with userparameters and device parameters, it is possible to use ``save`` and ``restore`` before and after ``.setsafe`` to return to ``NOSAFER`` mode, but note that such a save object is accessible to any procedures or file run in ``SAFER`` mode. A malicious file with an unbalanced restore could potentially restore back to a point where ``SAFER`` was not in operation. + + .. note:: + + This uses ``setpagedevice`` to change ``.LockSafetyParams``, so the page will be erased as a side effect of this operator. + + + +``- .locksafe -`` + The following is deprecated, see :ref:`-dSAFER<dSAFER>`. + + This operator sets the current device's ``.LockSafetyParams`` and the ``LockFilePermissions`` user parameter true as well as adding the paths on ``LIBPATH`` and ``FONTPATH`` and the paths given by the system params ``/GenericResourceDir`` and ``/FontResourceDir`` to the current ``PermitFileReading`` list of paths. + + If Ghostscript is started with ``-dNOSAFER`` or ``-dDELAYSAFER``, this operator can be used to enter ``SAFER`` mode with the current set of ``PermitFile...`` user parameters in effect. Since ``.setsafe`` sets the ``PermitFile...`` user parameters to empty arrays, a script or job server that needs to enable certain paths for file Reading, Writing and/or Control can use this operator to perform the locking needed to enter ``SAFER`` mode. + + For example, to enable reading everywhere, but disallow writing and file control (deleting and renaming files), the following can be used: + + .. code-block:: postscript + + { << /PermitFileReading [ (*) ] + /PermitFileWriting [ ] + /PermitFileControl [ ] + >> setuserparams + .locksafe + } stopped pop + + + In the above example, use of stopped will allow the use of this sequence on older versions of Ghostscript where ``.locksafe`` was not an operator. + + + .. note:: + + This uses ``setpagedevice`` to change ``.LockSafetyParams``, so the page will be erased as a side effect of this operator. + + See also :ref:`.LockSafetyParams<Language_LockSafetyParams>` and `User Parameters`_. + + +.. _Language_AddControlPath: + +``<name> <string> .addcontrolpath`` + + Adds a single path to the file access control lists. + + The ``<name>`` parameter can be one of: + + - ``/PermitFileReading`` + + - ``/PermitFileWriting`` + + - ``/PermitFileControl`` + + Whilst the string parameter is the path to be added to the requested list. + + .. note :: + + Any attempt to call this operator after ``.activatepathcontrol`` has been called will result in a ``Fatal`` error, and the interpreter will immediately exit. + + +.. _Language_ActivateControlPath: + +``.activatepathcontrol`` + Activates file access controls. Once activated, these access controls remain in place until the interpreter shuts down. + +``.currentpathcontrolstate`` + Returns true on the operand stack if file access control has been activated, false if not. + +``<dict> .genordered <dict> (default: /OutputType /Type3).``, ``<dict> .genordered <string> (/OutputType /ThreshString).``, ``<dict> .genordered <array> (/OutputType /TOSArray).`` + This operator creates an ordered dither screening pattern with the parameters from the dictionary, returning (by default) a PostScript HalftoneType 3 (threshold array based) dictionary suitable for use with ``sethalftone`` or as a component Halftone of a ``HalftoneType 5`` Halftone dictionary. The ``/OutputType`` parameter can also select other than Halftone Type 3 as the return paramter, ``<dict>`` has the following keys (all are optional): + + ``/Frequency`` + Integer; default value = 75 + + ``/Angle`` + Integer; default value = 0 + + ``/HResolution`` + Real or Integer; default value is device X resolution. + + ``/VResolution`` + Real or Integer; default value is device Y resolution. + + ``/DotShape`` + Integer; default value = 0 (CIRCLE). Other shapes available are: + + 1=REDBOOK, 2=INVERTED, 3=RHOMBOID, 4=LINE_X, 5=LINE_Y, 6=DIAMOND1, 7=DIAMOND2, 8=ROUNDSPOT + + ``/SuperCellSize`` + Integer; default value = 1 -- actual cell size determined by Frequency, Angle, H/V Resolution. + + A larger value will allow more levels to be attained. + + ``/Levels`` + Integer; default value = 1 -- actual number of gray levels is determined by Frequency and H/V Resolution. + + SuperCellSize may need to be specified large enough to achieve the requested number of gray levels. + + ``/OutputType`` + Name; default value = /Type3 (HalftoneType 3 dictionary). + + ``/ThreshString`` + First two bytes are width (high byte first), next two bytes are height, followed by the threshold array bytes (same as ``/Thresholds`` of the Type3 dictionary). + + ``/TOSArray`` + First element is the width, next is the height, followed by pairs X, then Y, of the turn-on-sequence of the threshold array. This information can be used to construct a threshold array with a transfer function "pickled into" the threshold array, which is useful if the turn-on-sequence has more than 256 pairs. Refer to ``toolbin``/``halftone``/``thresh_remap`` for more information. + +``.shellarguments`` + This operator is used to access the ``ARGUMENTS`` command line option. + + Relies on Ghostscript being called with the "``--``" command line option - see :ref:`Input Control<Use_Input Control>`. + + See examples in ``lib`` for more information. + + + +Device operators +"""""""""""""""""""""""""" + +``<device> copydevice <device>`` + Copies a device. The copy is writable and installable. The copy is created in the current VM (local or global), usually local VM for executing ordinary PostScript files. + +``<devicename> finddevice <device>`` + Creates a default instance of a device specified by name. The instance is created in global VM. If ``finddevice`` is called more than once with the same device name, it creates the default instance the first time, and returns the same instance thereafter. + +``<devicename> findprotodevice <device>`` + Finds the prototype of a device specified by name. A prototype can be used with ``getdeviceprops`` or other parameter-reading operators, but it is read-only and cannot be set with setdevice: it must be copied first. + +``<matrix> <width> <height> <palette> makeimagedevice <device>`` + Makes a new device that accumulates an image in memory. ``matrix`` is the initial transformation matrix: it must be orthogonal (that is, [a 0 0 b x y] or [0 a b 0 x y]). palette is a string of 2^N or 3 × 2^N elements, specifying how the 2^N possible pixel values will be interpreted. Each element is interpreted as a gray value, or as RGB values, multiplied by 255. For example, if you want a monochrome image for which 0=white and 1=black, the palette should be <ff 00>; if you want a 3-bit deep image with just the primary colors and their complements (ignoring the fact that 3-bit images are not supported), the palette might be ``<000000 0000ff 00ff00 00ffff ff0000 ff00ff ffff00 ffffff>``. At present, the palette must contain exactly 2, 4, 16, or 256 entries, and must contain an entry for black and an entry for white; if it contains any entries that aren't black, white, or gray, it must contain at least the six primary colors (red, green, blue, and their complements cyan, magenta, and yellow); aside from this, its contents are arbitrary. + + Alternatively, ``palette`` can be 16, 24, 32, or null (equivalent to 24). These are interpreted as: + + + .. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Palette + - Bits allocated per color + * - 16 + - 5 red, 6 green, 5 blue + * - 24 + - 8 red, 8 green, 8 blue + * - 32 + - 8C, 8M, 8Y, 8K + + + .. note:: + + One can also make an image device (with the same palette as an existing image device) by copying a device using the copydevice operator. + + +``<device> <index> <string> copyscanlines <substring>`` + Copies one or more scan lines from an image device into a string, starting at a given scan line in the image. The data is in the same format as for the image operator. It is an error if the device is not an image device or if the string is too small to hold at least one complete scan line. Always copies an integral number of scan lines. + +``<device> setdevice -`` + Sets the current device to the specified device. Also resets the transformation and clipping path to the initial values for the device. Signals an ``invalidaccess`` error if the device is a prototype or if :ref:`.LockSafetyParams<Language_LockSafetyParams>` is true for the current device. + + Some device properties may need to be set with ``putdeviceprops`` before ``setdevice`` is called. For example, the :title:`pdfwrite` device will try to open its output file, causing an ``undefinedfilename`` error if ``OutputFile`` hasn't been set to a valid filename. Another method in such cases is to use the level 2 operator instead: ``<< /OutputDevice /pdfwrite /OutputFile (MyPDF.pdf) >> setpagedevice``. + +``- currentdevice <device>`` + Gets the current device from the graphics state. + +``<device> getdeviceprops <mark> <name1> <value1> ... <namen> <valuen>`` + Gets the properties of a device. See the section on `device parameters`_ below for details. + +``<mark> <name1> <value1> ... <namen> <valuen> <device> putdeviceprops <device>`` + Sets properties of a device. May cause ``undefined``, ``invalidaccess``, ``typecheck``, ``rangecheck``, or ``limitcheck`` errors. + + +Filters +-------- + + +Standard filters +~~~~~~~~~~~~~~~~~~~~~~~ + +In its usual configuration, Ghostscript supports all the standard PostScript LanguageLevel 3 filters, both encoding and decoding, except that it does not currently support: + +- the ``EarlyChange`` key in the ``LZWEncode`` filter. + +Ghostscript also supports additional keys in the optional dictionary operands for some filters. For the ``LZWDecode`` filter: + +``InitialCodeLength <integer> (default 8)`` + An integer between 2 and 11 specifying the initial number of data bits per code. Note that the actual initial code length is 1 greater than this, to allow for the reset and end-of-data code values. + +``FirstBitLowOrder <boolean> (default false)`` + If true, codes appear with their low-order bit first. + +``BlockData <boolean> (default false)`` + If true, the data is broken into blocks in the manner specified for the GIF file format. + + +For the ``CCITTFaxEncode`` and ``CCITTFaxDecode`` filters: + +``DecodedByteAlign <integer> (default 1)`` + An integer N with the value 1, 2, 4, 8, or 16, specifying that decoded data scan lines are always a multiple of N bytes. The encoding filter skips data in each scan line from Columns to the next multiple of N bytes; the decoding filter pads each scan line to a multiple of N bytes. + + +Non-standard filters +~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the standard PostScript LanguageLevel 3 filters, Ghostscript supports the following non-standard filters. Many of these filters are used internally to implement standard filters or facilities; they are almost certain to remain, in their present form or a backward-compatible one, in future Ghostscript releases. + +``<target> /BCPEncode filter <file>``, ``<source> /BCPDecode filter <file>`` + Create filters that implement the Adobe Binary Communications Protocol. See Adobe documentation for details. + +``<target> <seed_integer> /eexecEncode filter <file>`` + Creates a filter for encrypting data into the encrypted format described in the Adobe Type 1 Font Format documentation. The ``seed_integer`` must be 55665 for the ``eexec`` section of a font, or 4330 for a ``CharString``. Note that for the ``eexec`` section of a font, this filter produces binary output and does not include the initial 4 (or lenIV) garbage bytes. + +``<source> <seed_integer> /eexecDecode filter <file>``, ``<source> <dict> /eexecDecode filter <file>`` + Creates a filter for decrypting data encrypted as described in the Adobe Type 1 Font Format documentation. The ``seed_integer`` must be 55665 or 4330 as described just above. PDF interpreters don't skip space characters after operator ``eexec``. Use ``keep_spaces = true`` for decoding embedded PDF fonts. Recognized dictionary keys are: + + .. code-block:: postscript + + seed <16-bit integer> (required) + lenIV <non-negative integer> (default=4) + eexec <bool> (default=false) + keep_spaces <bool> (default=false) + +``<target> /MD5Encode filter <file>`` + Creates a filter that produces the 16-byte MD5 digest of the input. Note that no output is produced until the filter is closed. + +``<source> <hex_boolean> /PFBDecode filter <file>`` + Creates a filter that decodes data in ``.PFB`` format, the usual semi-binary representation for Type 1 font files on IBM PC and compatible systems. If ``hex_boolean`` is true, binary packets are converted to hex; if false, binary packets are not converted. + + + +``<target> <dict> /PixelDifferenceEncode filter <file>``, ``<source> <dict> /PixelDifferenceDecode filter <file>`` + Implements the Predictor=2 pixel-differencing option of the LZW filters. Recognized keys are: + + .. code-block:: postscript + + Colors <integer> (1 to 4, default=1) + BitsPerComponent <integer> (1, 2, 4, or 8, default=8) + Columns <integer> (>= 0, required) + + See the Adobe PDF Reference Manual for details. + +``<target> <dict> /PNGPredictorEncode filter <file>``, ``<source> <dict> /PNGPredictorDecode filter <file>`` + Implements the "filter" algorithms of the Portable Network Graphics (PNG) graphics format. Recognized keys are: + + + .. list-table:: + :widths: 40 40 20 + :header-rows: 1 + + * - Key + - Range + - Default + * - ``Colors <integer>`` + - 1 to 16 + - 16 + * - ``BitsPerComponent <integer>`` + - 1, 2, 4, 8, or 16 + - 8 + * - ``Columns <integer>`` + - >= 0 + - 1 + * - ``Predictor <integer>`` + - 10 to 15 + - 15 + + The ``Predictor`` is the PNG algorithm number + 10 for the ``Encoding`` filter; the ``Decoding`` filter ignores ``Predictor``. 15 means the encoder attempts to optimize the choice of algorithm. For more details see the `PNG specification`_. + + + +``<target> /TBCPEncode filter <file>``, ``<source> /TBCPDecode filter <file>`` + Create filters that implement the Adobe Tagged Binary Communications Protocol. See Adobe documentation for details. + +``<target> /zlibEncode filter <file>``, ``<source> /zlibDecode filter <file>`` + Creates filters that use the data compression method variously known as 'zlib' (the name of a popular library that implements it), 'Deflate' (as in `RFC 1951`_, which is a detailed specification for the method), 'gzip' (the name of a popular compression application that uses it), or 'Flate' (Adobe's name). Note that the PostScript ``Flate`` filters are actually a combination of this filter with an optional predictor filter. + + + +Unstable filters +~~~~~~~~~~~~~~~~~~~~~~~ + +Some versions of Ghostscript may also support other non-standard filters for experimental purposes. The current version includes the following such filters, which are not documented further. No code should assume that these filters will exist in compatible form, or at all, in future versions. + +``<target/source> <string> ByteTranslateEncode/Decode filter <file>`` + ``string`` must be a string of exactly 256 bytes. Creates a filter that converts each input byte ``b`` to ``string[b]``. Note that the ``Encode`` and ``Decode`` filters operate identically: the client must provide a string for the ``Decode`` filter that is the inverse mapping of the ``string`` for the ``Encode`` filter. + +``<target/source> <dict> BoundedHuffmanEncode/Decode filter <file>`` + These filters encode and decode data using Huffman codes. Since these filters aren't used anywhere, we don't document them further, except to note the recognized dictionary keys, which must be set identically for encoding and decoding: + + .. code-block:: postscript + + FirstBitLowOrder <bool> (default=false) + MaxCodeLength <int> (default=16) + EndOfData <bool> (default=true) + EncodeZeroRuns <int> (default=256) + Tables <int_array> + + +``<target/source> <dict> BWBlockSortEncode/Decode filter <file>`` + This filter implements the Burroughs-Wheeler block sorting compression method, which we've heard is also used in the popular ``bzip2`` compression application. The only recognized dictionary key is: + + .. code-block:: postscript + + BlockSize <integer> (default=16384) + + + +Device parameters +--------------------- + + +Ghostscript supports the concept of device parameters for all devices, not just page devices. (For non-page devices, these are accessible through ``getdeviceprops`` and ``putdeviceprops``, as indicated above.) Here are the currently defined parameters for all devices: + + +.. _Language_LockSafetyParams: + +``.LockSafetyParams <boolean>`` + This parameter allows for improved system security by preventing PostScript programs from being able to change potentially dangerous device parameters such as ``OutputFile``. This parameter cannot be set false if it is already true. + + If this parameter is true for the current device, attempt to set a new device that has ``.LockSafetyParams`` false will signal an ``invalidaccess`` error. + + +``BitsPerPixel <integer> (usually read-only)`` + Number of bits per pixel. + +``.HWMargins [<four floats>]`` + Size of non-imageable regions around the edges of the page, in points (units of 1/72in; see the :ref:`notes on measurements<Devices_Notes on measurements>` in the documentation on :ref:`devices<Devices.htm>`). + + +``HWSize [<integer> <integer>]`` + X and Y size in pixels. + +``%MediaSource <integer>`` + The input tray key as determined by ``setpagedevice``. PostScript language programs don't set this parameter directly; they can request a particular tray through the ``MediaPosition`` ``setpagedevice`` parameter, but the ``setpagedevice`` logic need not necessarily honor the request. Devices which support switchable trays should implement ``%MediaSource`` in their ``put_params`` device procedure, but (unlike most other such parameters) need not implement corresponding reading logic in ``get_params``. + +``%MediaDestination <integer>`` + The output tray key as determined by ``setpagedevice``. Handling by devices should be parallel to ``%MediaSource``. + +``.IgnoreNumCopies <boolean>`` + Some page description languages support a ``NumCopies`` parameter. This parameter instructs the device to ignore this, producing only one copy of the document on output. Note that some devices ignore ``NumCopies`` regardless because of limitation of the output format or the implementation. + +``Name <string> (read-only)`` + The device name. Currently the same as ``OutputDevice``. + +``Colors, GrayValues, RedValues, GreenValues, BlueValues, ColorValues (usually read-only)`` + As for the ``deviceinfo`` operator of Display PostScript. ``Red``, ``Green``, ``Blue``, and ``ColorValues`` are only defined if ``Colors > 1``. + +``TextAlphaBits, GraphicsAlphaBits (usually read-only)`` + The number of bits of anti-aliasing information for text or graphics respectively. Legal values are 1 (no anti-aliasing, the default for most devices), 2, or 4. + + Because this feature relies upon rendering the input it is incompatible, and will generate an error on attempted use, with any of the vector output devices. + + +Ghostscript also supports the following read-only parameter that is not a true device parameter: + +``.EmbedFontObjects <integer>`` + If non-zero, indicates that the device may embed font objects (as opposed to bitmaps for individual characters) in the output. The purpose of this parameter is to disable third-party font renderers for such devices. (This is zero for almost all devices.) + +In addition, the following are defined per Adobe's documentation for the ``setpagedevice`` operator: + +.. code-block:: postscript + + Duplex (if supported) + HWResolution + ImagingBBox + Margins + LeadingEdge + MediaPosition + NumCopies (for printers only) + Orientation (if supported) + OutputDevice + PageOffset (write-only) + PageSize + ProcessColorModel (usually read-only) + +Some devices may only allow certain values for ``HWResolution`` and ``PageSize``. The null device ignores attempts to set ``PageSize``; its size is always ``[0 0]``. + +It should be noted that calling ``setpagedevice`` with one of the above keys may reset the effects of any ``pdfmark`` commands up to that point. In particular this is true of ``HWResolution``, a behavior that differs from Adobe Distiller. + +For raster printers and image format (jpeg*, tiff*, png* ...) devices these page device parameters are also defined: + + +``MaxBitmap <integer>`` + Maximum space for a full page raster image (bitmap) in memory. + This value includes the space for padding raster lines and for an array of pointers for each raster line, thus the ``MaxBitmap`` value to allow a given ``PageSize`` of a specific number of bits per pixel to be rendered in a full page buffer may be somewhat larger than the bitmap size alone. + +``BandListStorage <file|memory>`` + The default is determined by the make file macro ``BAND_LIST_STORAGE``. Since memory is always included, specifying ``-sBandListStorage=memory`` when the default is file will use memory based storage for the band list of the page. This is primarily intended for testing, but if the disk I/O is slow, band list storage in memory may be faster. + +``BufferSpace <integer>`` + Size of the buffer space for band lists, if the full page raster image (bitmap) is larger than ``MaxBitmap`` (see above.) + + The buffer space is used to collect display list (clist) commands for the bands and then to consolidate those commands when writing the clist to the selected ``BAND_LIST_STORAGE`` device (memory or file) set when Ghostscript is compiled. + + If ``MaxBitmap`` (above) forces banding mode, and if ``BufferSpace`` is large enough, the display list (``clist``) will consist of a single band. + + The ``BufferSpace`` will determine the size of the 'consolidation' buffer (above) even if the MaxBitmap value is low enough to force banding/clist mode. + + +``BGPrint <boolean>`` + With many printer devices, when the display list (``clist``) banding mode is being used, the page rendering and output can be performed in a background thread. The default value, false, causes the rendering and printing to be done in the same thread as the parser. When ``-dBGPrint=true``, the page output will be overlapped with parsing and writing the ``clist`` for the next page. + + If the device does not support background printing, rendering and printing will be performed as if ``-dBGPrint=false``. + + .. note:: + + The background printing thread will allocate a band buffer (size determined by the ``BufferSpace`` or ``BandBufferSpace`` values) in addition to the band buffer in the 'main' parsing thread. + + If ``NumRenderingThreads`` is ``> 0``, then the background printing thread will use the specified number of rendering threads as children of the background printing thread. The background printing thread will perform any processing of the raster data delivered by the rendering threads. Note that ``BGPrint`` is disabled for vector devices such as :title:`pdfwrite` and ``NumRenderingThreads`` has no effect on these devices either. + +``GrayDetection <boolean>`` + When true, and when the display list (``clist``) banding mode is being used, during writing of the ``clist``, the color processing logic collects information about the colors used before the device color profile is applied. This allows special devices that examine ``dev->icc_struct->pageneutralcolor`` with the information that all colors on the page are near neutral, i.e. monochrome, and converting the rendered raster to gray may be used to reduce the use of color toners/inks. + + Since the determination of whether or not the page uses colors is determined before the conversion to device colors, this information is independent of the device output profile. The determination has a small delta (``DEV_NEUTRAL`` and ``AB_NEUTRAL`` in ``base/gscms.h``) to allow colors close to neutral to be detected as neutral. Changing this value requires rebuilding. + + Among the devices distributed with the source, currently only the ``pnmcmyk`` device supports this parameter and will produce either a ``P7 PAM CMYK`` output or a ``P5 PGM Gray`` output depending on the use of color on the page. + + Also, the ``pageneutralcolor`` status can be interrogated as a device parameter of the same name. Using PostScript there are several methods: + + ``currentpagedevice /pageneutralcolor get`` + + ``mark currentdevice getdeviceprops .dicttomark /pageneutralcolor get`` + + ``/pageneutralcolor /GetDeviceParam .special_op { exch pop }{ //false } ifelse`` + + Note that the ``pageneutralcolor`` state is reset to false after the page is output, so this parameter is only valid immediately before ``showpage`` is executed, although the ``setpagedevice`` ``EndPage`` procedure can be used to check the state just prior to the actual output of the page that resets ``pagenuetralcolor``. For example: + + .. code-block:: postscript + + << /EndPage { + exch pop 2 ne dup { + currentpagedevice /pageneutralcolor get (pageneutralcolor: ) print = flush + } if + } + >> setpagedevice + + .. note:: + + Since ``-dGrayDetection=true`` requires extra checking during writing of the ``clist``, this option should only be used for devices that support the optimization of pages to monochrome, otherwise performance may be degraded for no benefit. + + Since ``GrayDetection=true`` is only effective when in ``clist`` (banding) mode, it is recommended to also force banding. For example: ``-dGrayDetection=true -dMaxBitmap=0``. + + +``NumRenderingThreads <integer>`` + When the display list (``clist``) banding mode is being used, bands can be rendered in separate threads. The default value, 0, causes the rendering of bands to be done in the same thread as the parser and device driver. ``NumRenderingThreads`` of 1 or higher results in bands rendering in the specified number of 'background' threads. + + The number of threads should generally be set to the number of available processor cores for best throughput. + + Note that each thread will allocate a band buffer (size determined by the ``BufferSpace`` or ``BandBufferSpace`` values) in addition to the band buffer in the 'main' thread. + + Additionally note that this parameter has no effect with devices which do not generally render to a bitmap output, such as the vector devices (e.g. :title:`pdfwrite`) and has no effect when rendering, but not using a ``clist``. See :ref:`Improving performance<Use_Improving Performance>`. + + + +``OutputFile <string>`` + An empty string means "send to printer directly", otherwise specifies the file name for output; ``%d`` is replaced by the page number for page-oriented output devices; on Unix systems ``%pipe%`` *command* writes to a pipe. (``|`` *command* also writes to a pipe, but is now deprecated). Also see the ``-o`` parameter. + + Attempts to set this parameter if ``.LockSafetyParams`` is true will signal an ``invalidaccess`` error. + +``OpenOutputFile <boolean>`` + If true, open the device's output file when the device is opened, rather than waiting until the first page is ready to print. + +``PageCount <integer> (read-only)`` + Counts the number of pages printed on the device. + +.. _Language_BandingParams: + +The following parameters are for use only by very specialized applications that separate band construction from band rasterization. Improper use may cause unpredictable errors. In particular, if you only want to allocate more memory for banding, to increase band size and improve performance, use the ``BufferSpace`` parameter, not ``BandBufferSpace``. + + + +``BandHeight <integer>`` + The height of bands when banding. 0 means use the largest band height that will fit within the ``BandBufferSpace`` (or ``BufferSpace``, if ``BandBufferSpace`` is not specified). If ``BandHeight`` is larger than the number of lines that will fit in the buffer, opening the device will fail. If the value is -1, the ``BandHeight`` will automatically be set to the page height (1 band for the entire page). This is primarily for developers debugging ``clist`` issues. + +``BandWidth <integer>`` + The width of bands in the rasterizing pass, in pixels. 0 means use the actual page width. A ``BandWidth`` value smaller than the width of the page will be ignored, and the actual page width will be used instead. + +``BandBufferSpace <integer>`` + The size of the band buffer in the rasterizing pass, in bytes. 0 means use the same buffer size as for the interpretation pass. + + +Ghostscript supports the following parameter for ``setpagedevice`` and ``currentpagedevice`` that is not a device parameter per se: + +``ViewerPreProcess <procedure>`` + Specifies a procedure to be applied to the page device dictionary before any other processing is done. The procedure may not alter the dictionary, but it may return a modified copy. This "hook" is provided for use by viewing programs such as ``GSview``. + + + + +User parameters +--------------------- + + + +Ghostscript supports the following non-standard user parameters: + +``ProcessDSCComment <procedure|null>`` + If not null, this procedure is called whenever the scanner detects a DSC comment (comment beginning with ``%%`` or ``%!``). There are two operands, the file and the comment (minus any terminating ``EOL``), which the procedure must consume. + +``ProcessComment <procedure|null>`` + If not null, this procedure is called whenever the scanner detects a comment (or, if ``ProcessDSCComment`` is also not null, a comment other than a ``DSC`` comment). The operands are the same as for ``ProcessDSCComment``. + +``LockFilePermissions <boolean>`` + If true, this parameter and the three ``PermitFile...`` parameters cannot be changed. Attempts to change any of the values when ``LockFilePermissions`` is true will signal ``invalidaccess``. Also, when this value is true, the file operator will give ``invalidaccess`` when attempting to open files (processes) using the ``%pipe`` device. + + Also when ``LockFilePermissions`` is true, strings cannot reference the parent directory (platform specific). For example (``../../xyz``) is illegal on unix, Windows and Macintosh, and (``[.#.#.XYZ]``) is illegal on VMS. + + This parameter is set true by the ``.setsafe`` and ``.locksafe`` operators. + + +``PermitFileReading <array of strings>``, ``PermitFileWriting <array of strings>``, ``PermitFileControl <array of strings>`` + These parameters specify paths where file reading, writing and the 'control' operations are permitted, respectively. File control operations are ``deletefile`` and ``renamefile``. For ``renamefile``, the filename for the current filename must match one of the paths on the ``PermitFileControl`` list, and the new filename must be on both the ``PermitFileControl`` and the ``PermitFileWriting`` lists of paths. + + The strings can contain wildcard characters as for the ``filenameforall`` operator and unless specifying a single file, will end with a ``*`` for directories (folders) to allow access to all files and sub-directories in that directory. + + .. note:: + + The strings are used for ``stringmatch`` operations similar to ``filenameforall``, thus on MS Windows platforms, use the '``/``' character to separate directories and filenames or use '``\\\\``' to have the string contain '``\\``' which will match a single '``\``' in the target filename (use of '``/``' is strongly recommended). + + The :ref:`SAFER<dSAFER>` mode and the ``.setsafe`` operator set all three lists to empty arrays, thus the only files that can be read are the ``%stdin`` device and on ``LIBPATH`` or ``FONTPATH`` or the ``Resource`` paths specified by the ``/FontResourceDir`` or ``/GenericResourceDir`` system params. Files cannot be opened for writing anywhere and cannot be deleted or renamed except for files created with the :ref:`.tempfile<Tempfile>` operator). + + +``AlignToPixels <integer>`` + Control sub-pixel positioning of character glyphs (where applicable). A value of 1 specifies alignment of text characters to pixels boundaries. A value of 0 to subpixels where the division factor is set by the device parameter ``TextAlphaBits``. If the latter is 1, the same rendering results regardless of the value of ``AlignToPixels``. The initial value defaults to 1, but this may be overridden by the command line argument ``-dAlignToPixels``. + + +.. _Language_GridFitTT: + +``GridFitTT <integer>`` + Control the use of True Type grid fitting. Ghostscript, by default, uses Freetype for rendering Truetype (and most other) glyphs (but other scaler/renderer libraries can be used), thus has access to a complete Truetype bytecode interpreter. + + This parameter controls the hinting of Truetype glyphs. + + - A value of 0 disables grid fitting for all True Type fonts (not generally recommended). + + - A value of 1 enables the grid fitting using the native Truetype hinting bytecode program(s). Fonts or glyphs with faulty bytecode program(s) will be rendered unhinted. + + - A value 2 is scaler/renderer dependent (generally, if no alternative hinting engine is available this will be equivalent to 1). With the Freetype (our default) this enables Freetype's built-in autohinter. + + - With Freetype, a value of 3 is effectively equivalent to 1. + + This parameter defaults to 1, but this may be overridden on the command line with ``-dGridFitTT=n``. + + + +Miscellaneous additions +--------------------------- + +Extended semantics of 'run' +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The operator run can take either a string or a file as its argument. In the latter case, it just runs the file, closing it at the end, and trapping errors just as for the string case. + +Decoding resources +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``Decoding`` is a Ghostscript-specific resource category. It contains various resources for emulating PostScript fonts with other font technologies. Instances of the ``Decoding`` category are tables which map PostScript glyph names to character codes used with TrueType, Intellifont, Microtype and other font formats. + + +Currently Ghostscript is capable of PostScript font emulation in 2 ways : + +1. Through :ref:`FAPI<Fonts FAPI>` plugins. +2. With TrueType font files, using the native font renderer, by specifying TrueType font names or files in ``Resource/Init/Fontmap.GS``. + + +``Decoding`` resources are not currently used by the native font renderer. + +An instance of the ``Decoding`` resource category is a dictionary. The dictionary keys are PostScript glyph names and the values are either character codes, or arrays of character codes. Arrays are used when a single name may be mapped to various character codes - in this case Ghostscript tries all alternatives until a success. The name of the resource instance should reflect the character set for which it maps. For example, ``/Unicode`` ``/Decoding`` resource maps to Unicode UTF-16. + +The rules for using ``Decoding`` resources in particular cases are specified in the configuration file ``Resource/Init/xlatmap``. See the file itself for more information. + +The file format for ``Decoding`` resource files is generic PostScript. Users may want to define custom ``Decoding`` resources. The ``ParseDecoding`` ``procset`` defined in ``Resource/Init/gs_ciddc.ps`` allows representation of the table in a comfortable form. + + + +CIDDecoding resources +~~~~~~~~~~~~~~~~~~~~~~~ + +``CIDDecoding`` resources are similar to ``Decoding`` resources, except they map ``Character Identifiers (CIDs)`` rather than glyph names. Another difference is that the native Ghostscript font renderer uses ``CIDDecoding`` resources while emulate ``CID`` fonts with TrueType or OpenType fonts. + +An instance of the ``CIDDecoding`` resource category is a dictionary of arrays. Keys in the dictionary are integers, which correspond to high order byte of a ``CID``. Values are 256-element arrays, and their indices correspond to the low order byte of a ``CID``. Each elemet of an array is either null, or character code (integer), or an array of character codes (integers). The zero code represents mapping to the default character. + +The dictionary includes the additional key ``CIDCount``. Its value is the maximal ``CID`` defined, plus one. + +The Ghostscript library is capable of generating some ``CIDDecoding`` instances automatically, using the appropriate ``CMap`` (character map) resources. This covers most of practical cases if the neccessary ``CMap`` resources are provided. See the table ``.CMapChooser`` in ``Resource/Init/gs_ciddc.ps`` for the names of automatically generated resources and associated ``CMaps``. They allow to mapping CNS1, GB1, Japan1, Japan2 and Korea1 CID sets to TrueType character sets known as Unicode (exactly UTF-16), Big5, GB1213, ShiftJIS, Johab and Wansung. + +The file format for ``CIDDecoding`` resource file is generic PostScript. Users may want to define custom resources to ``CIDDecoding`` resource category. + + +GlyphNames2Unicode +~~~~~~~~~~~~~~~~~~~~~ + +``GlyphNames2Unicode`` is an undocumented dictionary which Adobe PostScript printer driver uses to communicate with Adobe Distiller. In this dictionary the keys are glyph names, the values are Unicode UTF-16 codes for them. The dictionaly is stored in the ``FontInfo`` dictionary under the key ``GlyphNames2Unicode``. Ghostscript recognises it and uses to generate ``ToUnicode CMaps`` with :title:`pdfwrite`. + +Multiple Resource directories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since 8.10 release Ghostscript maintains multiple resource directories. + +Ghostscript does not distinguish ``lib`` and ``Resource`` directories. There is no file name conflicts because ``lib`` does not contain subdirectories, but ``Resource`` always store files in subdirectories. + +The search method with multiple resource directories appears not fully conforming to PLRM. We cannot unconditionally call ``ResourceFileName`` while executing ``findresource`` or ``resourcestatus``, ``resourceforall``, because per PLRM it always returns a single path. Therefore Ghostscript implements an extended search method in ``findresource``, ``resourcestatus`` and ``resourceforall``, which first calls ``ResourceFileName`` and checks whether the returned path points to an existing file. If yes, the file is used, otherwise Ghostscript searches all directories specified in ``LIB_PATH``. With a single resource directory it appears conforming to PLRM and equivalent to Adobe implementations. + +``ResourceFileName`` may be used for obtaining a path where a resource file to be installed. In this case Ghostscript to be invoked with ``-sGenericResourceDir=path``, specifying an absolute path. The default value for ``GenericResourceDir`` is a relative path. Therefore a default invocation with a PostScript installer will install resource files into ``/gs/Resource``. + + +Scripting the PDF interpreter +------------------------------- + +PostScript functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We have not previously documented the internals of the Ghostscript PDF interpreter, but we have, on occasion, provided solutions that rely upon scripting the interpreter from PostScript. This was possible because the interpreter was written in PostScript. + +From release 9.55.0 Ghostscript comes supplied with two PDF interpreters, the original written in PostScript and a brand-new interpreter written in C. While the new interpreter can be run as part of the ``GhostPDL`` family it has also been integrated into Ghostscript, and can be run from the PostScript environment in a similar fashion to the old interpreter. We plan to deprecate, and eventually remove, the old interpreter and carry on with the new one. + +Because we have supplied solutions in the past based on the old interpreter, we have had to implement the same capabilities in the integration of the new interpreter. Since this has meant discovering which internal portions were being used, working out how those function, and duplicating them anew, it seemed a good time to document these officially, so that in future the functionality would be available to all. + +The following functions existed in the original PDF interpreter and have been replicated for the new interpreter. It should be possible to use these for the forseeable future. + + +``<file> runpdf -`` + Called from the modified PostScript run operator (which copies ``stdin`` to a temp file if required). Checks for PDF collections, processes all requested pages. + +``<file> runpdfbegin -`` + This must be called before performing any further operations. Its exact action depends on which interpreter is being used, but it essentially sets up the environment to process the file as a PDF. + +``<int> pdfgetpage <pagedict> | <null>`` + ``int`` is a number from 1 to N indicating the desired page number from the PDF file. Returns the a dictionary containing various informational key/value pairs. If this fails, returns a null object. + +``- pdfshowpage_init -`` + In the PostScript PDF interpreter this simply adds 1 to the ``/DSCPageCount`` value in a dictionary. It has no effect in the new PDF interpreter but is maintained for backwards compatibility. + +``<pagedict> pdfshowpage_setpage <pagedict>`` + Takes a dictionary as returned from ``pdfgetpage``, extracts various parameters from it, and sets the media size for the page, taking into account the boxes, and requested ``Box``, ``Rotate`` value and ``PDFFitPage``. + +``<pagedict> pdfshowpage_finish -`` + Takes a dictionary as returned from ``pdfgetpage``, renders the page content executes ``showpage`` to transfer the rendered content to the device. + +``- runpdfend -`` + Terminates the PDF processing, executes restore and various cleanup activities. + +``<file> pdfopen <dict>`` + Open a PDF file and read the header, trailer and cross-reference. + +``<dict> pdfclose -`` + Terminates processing the original PDF file object. The dictionary parameter should be the one returned from ``pdfopen``. + +``<pagedict> pdfshowpage -`` + Takes a dictionary returned from ``pdfgetpage`` and calls the ``pdfshowpage_init``, ``pdfshowpage_setpage``, ``pdfshowpage_finish`` trio to start the page, set up the media and render the page. + +``<int> <int> dopdfpages -`` + The integers are the first and last pages to be run from the file. Runs a loop from the fist integer to the last. + + .. note:: + + If the current dictionary contains a ``PDFPageList`` array the two values on the stack are ignored and we use the range triples from that array (even/odd, start, end) to determine the pages to process. Page numbers for start and end are ``1..lastpage`` and even/odd is 1 for odd, 2 for even, otherwise 0. Uses ``pdfshowpage`` to actually render the page. + +``- runpdfpagerange <int> <int>`` + Processes the PostScript ``/FirstPage``, ``/LastPage`` and ``/PageList`` parameters. These are used together to build an internal array of page numbers to run, which is used by ``dopdfpages`` to actually process the pages if ``PageList`` is present, and a ``FirstPage`` and ``LastPage`` value. + + Despite the name this function does not actually 'run' any pages at all. + + Normal operation simply calls ``runpdf`` with an opened-for-read PostScript file object. The table below shows the normal calling sequence: + + + .. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Function + - Calls + - Calls + - Calls + * - runpdf + - runpdfbegin + - pdfopen + - + * - + - process_trailer_attrs + - + - + * - + - runpdfpagerange + - + - + * - + - dopdfpages + - pdfgetpage + - + * - + - + - pdfshowpage + - pdfshowpage_init + * - + - + - + - pdfshowpage_setpage + * - + - + - + - pdfshowpage_finish + * - + - runpdfend + - pdfclose + - + + It is important to get the number of spots and the presence of transparency correct when rendering. Failure to do so will lead to odd output, and potentially crahses. This can be important in situations such as N-up ordering. + + As an example, if we have 2 A4 pages and want to render them side-by-side on A3 media, we might set up the media size to A3, draw the first page contents, translate the origin, draw the second page contents and then render the final content. If the first PDF page did not contain transparency, but the second did, it would be necessary to set ``/PageHasTransparency`` before drawing the first PDF page. + + +PostScript operators interfacing to the PDF interpreter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PostScript functions documented above must somehow interface with the actual PDF interpreter, and this is done using a small number of custom PostScript operators. These operators do not exist in standard PostScript; they are specific to the Ghostscript implementation. These operators are documented here for the benefit of any developers wishing to use them directly. + + + +``dict .PDFInit <PDFContext>`` + Initialises an instance of the PDF interpreter. ``dict`` is an optional dictionary that contains any interpreter-level switches, such as ``PDFDEBUG``, this is used to set the initial state of the PDF interpreter. The return value is a ``PDFContext`` object which is an opaque object to be used with the other PDF operators. + +``filename PDFContext .PDFFile -`` + Opens a named file and associates it with the instance of the PDF interpreter. Filename is a string containing a fully qualified path to the PDF file to open, this file must have been made accesible by setting ``--permit-file-read``. + +``file PDFContext .PDFStream -`` + Takes an already open (disk-based) file and associates it with the instance of the PDF interpreter. + +``PDFcontext .PDFClose -`` + If the context contains an open PDF file which was opened via the ``.PDFfile`` operator, this closes the file. Files associated with the context by the ``.PDFStream`` operator are unaffected. Regardless of the source it then shuts down the PDF interpreter and frees the associated memory. + +``PDFContext .PDFInfo dict`` + ``PDFContext`` is a ``PDFContext`` object returned from a previous call to ``.PDFInit``. The returned dictionary contains various key/value pairs with useful file level information: + + .. code-block:: postscript + + /NumPages int + /Creator string + /Producer string + /IsEncrypted boolean + + +``PDFContext .PDFMetadata -`` + ``PDFContext`` is a ``PDFContext`` object returned from a previous call to ``.PDFInit``. For the benefit of high level devices, this is a replacement for 'process_trailer_attrs' which is a seriously misnamed function now. This function needs to write any required output intents, load and send ``Outlines`` to the device, copy the Author, Creator, Title, Subject and Keywords from the Info dict to the output device, copy Optional Content Properties (``OCProperties``) to the output device. If an AcroForm is present send all its fields and link widget annotations to fields, and finally copy the ``PageLabels``. If we add support for anything else, it will be here too. + +``PDFContext int .PDFPageInfo -`` + The integer argument is the page number to retrieve information for. This value starts from zero for the first page. Returns a dictionary with the following key/value pairs: + + .. code-block:: postscript + + /UsesTransparency true|false + /NumSpots integer containing the number of spot inks on this page + /MediaBox [llx lly urx ury] + /HasAnnots true|false + + May also contain (if they are present in the Page dictionary): + + .. code-block:: postscript + + /ArtBox [llx lly urx ury] + /CropBox [llx lly urx ury] + /BleedBox [llx lly urx ury] + /TrimBox [llx lly urx ury] + /UserUnit int + /Rotate number + +``PDFcontext int .PDFPageInfoExt -`` + As per ``.PDFPageInfo`` above but returns 'Extended' information. This consists of two additional arrays in the returned dictionary: + + .. code-block:: postscript + + /Spots array of names, may be empty + /Fonts array of dictionaries, one dictionary per font used on the page. + + + Each font dictionary contains: + + .. code-block:: postscript + + /BaseFont string containing the name of the font. + /Subtype string containing the type of the font, as per the PDF Reference. + /ObjectNum if present, the object number of the font in the file (fonts may be defined inline and have no object number). + /Embedded boolean indicating if the font's FontDescriptor includes a FontFile and is therefore embedded. + + Type 0 fonts also contain: + + .. code-block:: postscript + + /Descendants an array containing a single font dictionary, contents as above. + + +``PDFContext int .PDFDrawPage -`` + ``PDFContext`` is a ``PDFContext`` object returned from a previous call to ``.PDFInit``. The integer argument is the page number to be processed. Interprets the page content stream(s) of the specified page using the current graphics state. + +``PDFContext int .PDFDrawAnnots -`` + ``PDFContext`` is a ``PDFContext`` object returned from a previous call to ``.PDFInit``. The integer argument is the page number to be processed. + + Renders the Annotations (if any) of the specified page using the current graphics state For correct results, the graphics state when this operator is run should be the same as when PDFDrawPage is executed. + + .. note:: + + The ``PDFContext`` object created by ``PDFInit`` must (clearly) have a PDF file associated with it before you can usefully use it. Attempting to use a ``PDFContext`` with any of the processing operators (e.g. ``.PDFDrawPage``) before using either ``.PDFStream`` of ``.PDFFile`` to associate a file with the context will result in an error. + + + + +.. External Links + +.. _PNG specification: http://www.w3.org/TR/WD-png-960128.html +.. _RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + +.. include:: footer.rst diff --git a/doc/src/LanguageBindings.rst b/doc/src/LanguageBindings.rst new file mode 100644 index 00000000..7a6df7ac --- /dev/null +++ b/doc/src/LanguageBindings.rst @@ -0,0 +1,131 @@ +.. title:: Language Bindings + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + + + + +Language Bindings +======================= + +The core of Ghostscript is written in C, but also supports language bindings for the following programming languages: + +- C# +- Java +- Python + + +All of the above languages have equivalent methods as defined in the :ref:`C API<API.htm>`. Java and C# provide additional helper methods to make the use of the API easier for certain applications. These languages also provide example viewers that make use of these methods. + +This developer documentation is organized by programming language type and includes API reference and sample code. + +Before using the language bindings first ensure that Ghostscript is built for your platform before proceeding. See: + +- :ref:`Building with Visual Studio<Make Building with Visual Studio>` + +- :ref:`Building with MacOS<Make Building with MacOS>` + +- :ref:`Building with Unix<Make Building with Unix>` + + + +The C API +-------------- + +Ghostscript has been in development for over thirty years and is written in C. The API has evolved over time and is continually being developed. The language bindings into Ghostscript will attempt to mirror this evolution and match the current :ref:`C API<API.htm>` as much as possible. + +Licensing +----------------- + +Before using Ghostscript, please make sure that you have a valid license to do so. There are two available licenses; make sure you pick the one whose terms you can comply with. + + +Open Source license +~~~~~~~~~~~~~~~~~~~~~~~ + +If your software is open source, you may use Ghostscript under the terms of the GNU Affero General Public License. + +This means that all of the source code for your complete app must be released under a compatible open source license! + +It also means that you may not use any proprietary closed source libraries or components in your app. + +Please read the full text of the AGPL license agreement from the FSF web site + +If you cannot or do not want to comply with these restrictions, you must acquire a `commercial license`_ instead. + +.. raw:: html + + <button class="cta orange" onclick="window.location='https://artifex.com/licensing/'">Find out more about Licensing</button> + <p></p> + + +Commercial license +~~~~~~~~~~~~~~~~~~~~~~ + +If your project does not meet the requirements of the AGPL, please contact our sales team to discuss a commercial license. Each Artifex commercial license is crafted based on your individual use case. + +.. raw:: html + + <button class="cta orange" onclick="window.location='https://artifex.com/contact/'">CONTACT US</button> + <p></p> + + + + + +Demo code +----------- + +Please locate the ``demos`` folder in your ``ghostpdl`` source code download from the `GhostPDL repository`_ to find sample code demonstrating the language bindings in action. + + + + + +C# +----------- + +.. toctree:: + + LanguageBindingsCSharp.rst + + +Java +----------- + +.. toctree:: + + LanguageBindingsJava.rst + + +Python +----------- + +.. toctree:: + + LanguageBindingsPython.rst + + + + + + + + + + + + + + + +.. External links + +.. _commercial license: https://artifex.com/licensing/commercial/ +.. _.NET: https://dotnet.microsoft.com/ +.. _Visual Studio: https://visualstudio.microsoft.com/ +.. _Mono: https://www.mono-project.com/ +.. _GhostPDL repository: https://ghostscript.com/releases/gpdldnld.html diff --git a/doc/src/LanguageBindingsCSharp.rst b/doc/src/LanguageBindingsCSharp.rst new file mode 100644 index 00000000..5b935a8e --- /dev/null +++ b/doc/src/LanguageBindingsCSharp.rst @@ -0,0 +1,2148 @@ +.. title:: C# + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + + +Introduction +======================= + +In the GhostPDL repository a sample C# project can be found in ``/demos/csharp``. + +Within this project the following namespaces and corresponding C# files are of relevance: + +- GhostAPI_ ``ghostapi.cs`` +- GhostNET_ ``ghostnet.cs`` +- GhostMono_ ``ghostmono.cs`` + + + +Platform & setup +======================= + + +Ghostscript should be built as a shared library for your platform. + +See :ref:`Building Ghostscript<Building Ghostscript>`. + + +GhostAPI +======================= + +:title:`GhostAPI` is the main wrapper responsible for bridging over to the C library and ensuring that the correct DLLs are imported. + +:title:`GhostAPI` contains the ``ghostapi`` class which does not need to be instantiated as it provides public static methods. These methods, which mirror their C counterparts, are as follows: + + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Method + - Description + * - gsapi_revision_ + - Returns the revision numbers and strings of the Ghostscript interpreter library. + * - gsapi_new_instance_ + - Create a new instance of Ghostscript. + * - gsapi_delete_instance_ + - Destroy an instance of Ghostscript. + * - gsapi_set_stdio_with_handle_ + - Set the callback functions for ``stdio``, together with the handle to use in the callback functions. + * - gsapi_set_stdio_ + - Set the callback functions for ``stdio``. + * - gsapi_set_poll_with_handle_ + - Set the callback function for polling, together with the handle to pass to the callback function. + * - gsapi_set_poll_ + - Set the callback function for polling. + * - gsapi_set_display_callback_ + - *deprecated* + * - gsapi_register_callout_ + - This call registers a callout handler. + * - gsapi_deregister_callout_ + - This call deregisters a previously registered callout handler. + * - gsapi_set_arg_encoding_ + - Set the encoding used for the interpretation of all subsequent args supplied via the gsapi interface on this instance. + * - gsapi_set_default_device_list_ + - Set the string containing the list of default device names. + * - gsapi_get_default_device_list_ + - Returns a pointer to the current default device string. + * - gsapi_init_with_args_ + - Initialise the interpreter. + * - :ref:`gsapi_run_*<gsapi_run_asterisk>` + - (Wildcard for various "run" methods). + * - gsapi_exit_ + - Exit the interpreter. + * - gsapi_set_param_ + - Set a parameter. + * - gsapi_get_param_ + - Get a parameter. + * - gsapi_enumerate_params_ + - Enumerate the current parameters. + * - gsapi_add_control_path_ + - Add a (case sensitive) path to one of the lists of permitted paths for file access. + * - gsapi_remove_control_path_ + - Remove a (case sensitive) path from one of the lists of permitted paths for file access. + * - gsapi_purge_control_paths_ + - Clear all the paths from one of the lists of permitted paths for file access. + * - gsapi_activate_path_control_ + - Enable/Disable path control. + * - gsapi_is_path_control_active_ + - Query whether path control is activated or not. + + +:title:`GhostAPI` contains some essential structs & enums as well as a static class for some constants, finally it contains the main ``GSAPI`` class which holds the key methods which interface with the C library. + + + + + +Structs and Enums +------------------- + + +``gsapi_revision_t`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +This struct is used to contain information pertinent to the version of Ghostscript. + + +.. code-block:: csharp + + public struct gsapi_revision_t + { + public IntPtr product; + public IntPtr copyright; + public int revision; + public int revisiondate; + } + + +``gs_set_param_type`` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: csharp + + public enum gs_set_param_type + { + gs_spt_invalid = -1, + gs_spt_null = 0, /* void * is NULL */ + gs_spt_bool = 1, /* void * is NULL (false) or non-NULL (true) */ + gs_spt_int = 2, /* void * is a pointer to an int */ + gs_spt_float = 3, /* void * is a float * */ + gs_spt_name = 4, /* void * is a char * */ + gs_spt_string = 5, /* void * is a char * */ + gs_spt_long = 6, /* void * is a long * */ + gs_spt_i64 = 7, /* void * is an int64_t * */ + gs_spt_size_t = 8, /* void * is a size_t * */ + gs_spt_parsed = 9, /* void * is a pointer to a char * to be parsed */ + gs_spt_more_to_come = 1 << 31 + }; + + +``gsEncoding`` +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public enum gsEncoding + { + GS_ARG_ENCODING_LOCAL = 0, + GS_ARG_ENCODING_UTF8 = 1, + GS_ARG_ENCODING_UTF16LE = 2 + }; + + + +Constants +------------------- + +Constants are stored in the static class ``gsConstants`` for direct referencing. + + +``gsConstants`` +~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: csharp + + static class gsConstants + { + public const int E_QUIT = -101; + public const int GS_READ_BUFFER = 32768; + public const int DISPLAY_UNUSED_LAST = (1 << 7); + public const int DISPLAY_COLORS_RGB = (1 << 2); + public const int DISPLAY_DEPTH_8 = (1 << 11); + public const int DISPLAY_LITTLEENDIAN = (1 << 16); + public const int DISPLAY_BIGENDIAN = (0 << 16); + } + + + + +GSAPI +------------------- + + + +Methods contained within are explained below. + +:ref:`gsapi_run_*<csharp_gsapi_run_asterisk>` and gsapi_exit_ methods return an ``int`` code which can be interpreted as follows: + + +.. list-table:: + :header-rows: 1 + + * - code + - status + * - ``0`` + - no error + * - ``gsConstants.E_QUIT`` + - "quit" has been executed. This is not an error. gsapi_exit_ must be called next + * - ``<0`` + - error + + + +.. note:: + + For full details on these return codes please see :ref:`The C API return codes<API_Return codes>`. + + All :title:`GSAPI` methods aside from ``gsapi_revision`` and ``gsapi_new_instance`` should pass an instance of Ghostscript as their first parameter with an ``IntPtr`` instance + + + + + +``gsapi_revision`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This method returns the revision numbers and strings of the Ghostscript interpreter library; you should call it before any other interpreter library functions to make sure that the correct version of the Ghostscript interpreter has been loaded. + + + +.. code-block:: csharp + + public static extern int gsapi_revision(ref gsapi_revision_t vers, int size); + + +.. note:: + + The method should write to a reference variable which conforms to the struct `gsapi_revision_t`_. + + + + +``gsapi_new_instance`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates a new instance of Ghostscript. This instance is passed to most other :title:`GSAPI` methods. Unless Ghostscript has been compiled with the ``GS_THREADSAFE`` define, only one instance at a time is supported. + +.. code-block:: csharp + + public static extern int gsapi_new_instance(out IntPtr pinstance, + IntPtr caller_handle); + +.. note:: + + The method returns a pointer which represents your instance of Ghostscript. + + + + + +``gsapi_delete_instance`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Destroy an instance of Ghostscript. Before you call this, Ghostscript must have finished. If Ghostscript has been initialised, you must call gsapi_exit_ beforehand. + + +.. code-block:: csharp + + public static extern void gsapi_delete_instance(IntPtr instance); + + +**Sample code:** + +.. code-block:: csharp + + GSAPI.gsapi_delete_instance(gsInstance); + gsInstance = IntPtr.Zero; + + + + +``gsapi_set_stdio_with_handle`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback functions for ``stdio``, together with the handle to use in the callback functions. The stdin callback function should return the number of characters read, ``0`` for ``EOF``, or ``-1`` for ``error``. The ``stdout`` and ``stderr`` callback functions should return the number of characters written. + +.. note:: + + These callbacks do not affect output device I/O when using "%stdout" as the output file. In that case, device output will still be directed to the process "stdout" file descriptor, not to the ``stdio`` callback. + + +.. code-block:: csharp + + public static extern int gsapi_set_stdio_with_handle(IntPtr instance, + gs_stdio_handler stdin, + gs_stdio_handler stdout, + gs_stdio_handler stderr, + IntPtr caller_handle); + + + + +``gsapi_set_stdio`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback functions for ``stdio``. The handle used in the callbacks will be taken from the value passed to gsapi_new_instance_. Otherwise the behaviour of this function matches gsapi_set_stdio_with_handle_. + + +.. code-block:: csharp + + public static extern int gsapi_set_stdio_with_handle(IntPtr instance, + gs_stdio_handler stdin, + gs_stdio_handler stdout, + gs_stdio_handler stderr); + + + + +``gsapi_set_poll_with_handle`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback function for polling, together with the handle to pass to the callback function. This function will only be called if the Ghostscript interpreter was compiled with ``CHECK_INTERRUPTS`` as described in ``gpcheck.h``. + +The polling function should return zero if all is well, and return negative if it wants Ghostscript to abort. This is often used for checking for a user cancel. This can also be used for handling window events or cooperative multitasking. + +The polling function is called very frequently during interpretation and rendering so it must be fast. If the function is slow, then using a counter to return 0 immediately some number of times can be used to reduce the performance impact. + + +.. code-block:: csharp + + public static extern int gsapi_set_poll_with_handle(IntPtr instance, + gsPollHandler pollfn, + IntPtr caller_handle); + + + +``gsapi_set_poll`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback function for polling. The handle passed to the callback function will be taken from the handle passed to gsapi_new_instance_. Otherwise the behaviour of this function matches gsapi_set_poll_with_handle_. + + +.. code-block:: csharp + + public static extern int gsapi_set_poll(IntPtr instance, + gsPollHandler pollfn); + + + +``gsapi_set_display_callback`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call is deprecated; please use gsapi_register_callout_ to register a :ref:`callout handler<gs_callout>` for the display device in preference. + + +.. code-block:: csharp + + public static extern int gsapi_set_display_callback(IntPtr pinstance, + IntPtr caller_handle); + + +``gsapi_register_callout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call registers a :ref:`callout handler<gs_callout>`. + +.. code-block:: csharp + + public static extern int gsapi_register_callout(IntPtr instance, + gsCallOut callout, + IntPtr callout_handle); + + + +``gsapi_deregister_callout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call deregisters a :ref:`callout handler<gs_callout>` previously registered with gsapi_register_callout_. All three arguments must match exactly for the :ref:`callout handler<gs_callout>` to be deregistered. + +.. code-block:: csharp + + public static extern int gsapi_deregister_callout(IntPtr instance, + gsCallOut callout, + IntPtr callout_handle); + + + + +``gsapi_set_arg_encoding`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the encoding used for the interpretation of all subsequent arguments supplied via the :title:`GhostAPI` interface on this instance. By default we expect args to be in encoding 0 (the 'local' encoding for this OS). On Windows this means "the currently selected codepage". On Linux this typically means ``utf8``. This means that omitting to call this function will leave Ghostscript running exactly as it always has. Please note that use of the 'local' encoding is now deprecated and should be avoided in new code. This must be called after gsapi_new_instance_ and before gsapi_init_with_args_. + + +.. code-block:: csharp + + public static extern int gsapi_set_arg_encoding(IntPtr instance, + int encoding); + + + +``gsapi_set_default_device_list`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the string containing the list of default device names, for example "display x11alpha x11 bbox". Allows the calling application to influence which device(s) Ghostscript will try, in order, in its selection of the default device. This must be called after gsapi_new_instance_ and before gsapi_init_with_args_. + +.. code-block:: csharp + + public static extern int gsapi_set_default_device_list(IntPtr instance, + IntPtr list, + ref int listlen); + + + +``gsapi_get_default_device_list`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Returns a pointer to the current default device string. This must be called after gsapi_new_instance_ and before gsapi_init_with_args_. + + +.. code-block:: csharp + + public static extern int gsapi_get_default_device_list(IntPtr instance, + ref IntPtr list, + ref int listlen); + +``gsapi_init_with_args`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To initialise the interpreter, pass your ``instance`` of Ghostscript, your argument count, ``argc`` and your argument variables, ``argv``. + + +.. code-block:: csharp + + public static extern int gsapi_init_with_args(IntPtr instance, + int argc, + IntPtr argv); + + + + +.. _csharp_gsapi_run_asterisk: + + +``gsapi_run_*`` +~~~~~~~~~~~~~~~~~~ + +If these functions return ``<= -100``, either quit or a fatal error has occured. You must call gsapi_exit_ next. The only exception is gsapi_run_string_continue_ which will return ``gs_error_NeedInput`` if all is well. + +There is a 64 KB length limit on any buffer submitted to a ``gsapi_run_*`` function for processing. If you have more than 65535 bytes of input then you must split it into smaller pieces and submit each in a separate gsapi_run_string_continue_ call. + + +``gsapi_run_string_begin`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public static extern int gsapi_run_string_begin(IntPtr instance, + int usererr, + ref int exitcode); +``gsapi_run_string_continue`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public static extern int gsapi_run_string_continue(IntPtr instance, + IntPtr command, + int count, + int usererr, + ref int exitcode); + + + +``gsapi_run_string_with_length`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public static extern int gsapi_run_string_with_length(IntPtr instance, + IntPtr command, + uint length, + int usererr, + ref int exitcode); +``gsapi_run_string`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public static extern int gsapi_run_string(IntPtr instance, + IntPtr command, + int usererr, + ref int exitcode); +``gsapi_run_string_end`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public static extern int gsapi_run_string_end(IntPtr instance, + int usererr, + ref int exitcode); + + +``gsapi_run_file`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + public static extern int gsapi_run_file(IntPtr instance, + IntPtr filename, + int usererr, + ref int exitcode); + + + + +``gsapi_exit`` +~~~~~~~~~~~~~~~~ + + +Exit the interpreter. This must be called on shutdown if gsapi_init_with_args_ has been called, and just before gsapi_delete_instance_. + + +.. code-block:: csharp + + public static extern int gsapi_exit(IntPtr instance); + + + +``gsapi_set_param`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sets a parameter. + +Broadly, this is equivalent to setting a parameter using ``-d``, ``-s`` or ``-p`` on the command line. This call cannot be made during a gsapi_run_string_ operation. + +Parameters in this context are not the same as 'arguments' as processed by gsapi_init_with_args_, but often the same thing can be achieved. For example, with gsapi_init_with_args_, we can pass "-r200" to change the resolution. Broadly the same thing can be achieved by using gsapi_set_param_ to set a parsed value of "<</HWResolution [ 200.0 200.0 ]>>". + +Internally, when we set a parameter, we perform an ``initgraphics`` operation. This means that using gsapi_set_param_ other than at the start of a page is likely to give unexpected results. + +Attempting to set a parameter that the device does not recognise will be silently ignored, and that parameter will not be found in subsequent gsapi_get_param_ calls. + + +.. code-block:: csharp + + public static extern int gsapi_set_param(IntPtr instance, + IntPtr param, + IntPtr value, + gs_set_param_type type); + + + +.. note:: + + The type argument, as a ``gs_set_param_type``, dictates the kind of object that the value argument points to. + + For more on the C implementation of parameters see: :ref:`Ghostscript parameters in C<Use_Setting Parameters>`. + + + +``gsapi_get_param`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Retrieve the current value of a parameter. + +If an error occurs, the return value is negative. Otherwise the return value is the number of bytes required for storage of the value. Call once with value ``NULL`` to get the number of bytes required, then call again with value pointing to at least the required number of bytes where the value will be copied out. Note that the caller is required to know the type of value in order to get it. For all types other than ``gs_spt_string``, ``gs_spt_name``, and ``gs_spt_parsed`` knowing the type means you already know the size required. + +This call retrieves parameters/values that have made it to the device. Thus, any values set using ``gs_spt_more_to_come`` without a following call omitting that flag will not be retrieved. Similarly, attempting to get a parameter before gsapi_init_with_args_ has been called will not list any, even if gsapi_set_param_ has been used. + +Attempting to read a parameter that is not set will return ``gs_error_undefined`` (-21). Note that calling gsapi_set_param_ followed by gsapi_get_param_ may not find the value, if the device did not recognise the key as being one of its configuration keys. + +For further documentation please refer to :ref:`the C API<API_gsapi_get_param>`. + + +.. code-block:: csharp + + public static extern int gsapi_get_param(IntPtr instance, + IntPtr param, + IntPtr value, + gs_set_param_type type); + + + +``gsapi_enumerate_params`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enumerate the current parameters. Call repeatedly to list out the current parameters. + +The first call should have ``iter = NULL``. Subsequent calls should pass the same pointer in so the iterator can be updated. Negative return codes indicate error, 0 success, and 1 indicates that there are no more keys to read. On success, key will be updated to point to a null terminated string with the key name that is guaranteed to be valid until the next call to gsapi_enumerate_params_. If type is non ``NULL`` then the pointer type will be updated to have the type of the parameter. + +.. note:: + + Only one enumeration can happen at a time. Starting a second enumeration will reset the first. + +The enumeration only returns parameters/values that have made it to the device. Thus, any values set using the ``gs_spt_more_to_come`` without a following call omitting that flag will not be retrieved. Similarly, attempting to enumerate parameters before gsapi_init_with_args_ has been called will not list any, even if gsapi_set_param_ has been used. + + +.. code-block:: csharp + + public static extern int gsapi_enumerate_params(IntPtr instance, + out IntPtr iter, + out IntPtr key, + IntPtr type); + + + +``gsapi_add_control_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add a (case sensitive) path to one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + +.. code-block:: csharp + + public static extern int gsapi_add_control_path(IntPtr instance, + int type, + IntPtr path); + +``gsapi_remove_control_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remove a (case sensitive) path from one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + +.. code-block:: csharp + + public static extern int gsapi_remove_control_path(IntPtr instance, + int type, + IntPtr path); + +``gsapi_purge_control_paths`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Clear all the paths from one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + +.. code-block:: csharp + + public static extern void gsapi_purge_control_paths(IntPtr instance, + int type); + + + +``gsapi_activate_path_control`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enable/Disable path control (i.e. whether paths are checked against :ref:`permitted paths<Use Safer>` before access is granted). + + +.. code-block:: csharp + + public static extern void gsapi_activate_path_control(IntPtr instance, + int enable); + + +``gsapi_is_path_control_active`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Query whether path control is activated or not. + +.. code-block:: csharp + + public static extern int gsapi_is_path_control_active(IntPtr instance); + + + +Callback and Callout prototypes +-------------------------------------- + +:title:`GSAPI` also defines some prototype pointers which are defined as follows. + +``gs_stdio_handler`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: csharp + + /* Callback proto for stdio */ + public delegate int gs_stdio_handler(IntPtr caller_handle, + IntPtr buffer, + int len); +``gsPollHandler`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: csharp + + /* Callback proto for poll function */ + public delegate int gsPollHandler(IntPtr caller_handle); + + +.. _gs_callout: + +``gsCallOut`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: csharp + + /* Callout proto */ + public delegate int gsCallOut(IntPtr callout_handle, + IntPtr device_name, + int id, + int size, + IntPtr data); + + +GhostNET +======================= + +:title:`GhostNET` is the `.NET`_ interface into :title:`GhostAPI`. It exemplifies how to do more complex operations involving multiple API calls and sequences. See the table below for the main methods: + + +.. list-table:: + :header-rows: 1 + :widths: 20 75 5 + + * - Method + - Description + - Notes + * - :ref:`GetVersion<GhostNET_GetVersion>` + - Returns the version of Ghostscript. + - + * - :ref:`DisplayDeviceOpen<GhostNET_DisplayDeviceOpen>` + - Sets up the display device ahead of time. + - + * - :ref:`DisplayDeviceClose<GhostNET_DisplayDeviceClose>` + - Closes the display device and deletes the instance. + - + * - :ref:`GetPageCount<GhostNET_GetPageCount>` + - Returns the page count for the document. + - + * - :ref:`CreateXPS<GhostNET_CreateXPS>` + - Launches a thread to create an XPS document for Windows printing. + - :ref:`asynchronous<Delegates>` + * - :ref:`DistillPS<GhostNET_DistillPS>` + - Launches a thread rendering all the pages of a supplied PostScript file to a PDF. + - :ref:`asynchronous<GhostNET_Delegates>` + * - :ref:`DisplayDeviceRunFile<GhostNET_DisplayDeviceRunFile>` + - Launches a thread to run a file with the display device. + - :ref:`asynchronous<GhostNET_Delegates>` + * - :ref:`DisplayDeviceRenderThumbs<GhostNET_DisplayDeviceRenderThumbs>` + - Launches a thread rendering all the pages with the display device to collect thumbnail images. + - :ref:`asynchronous<GhostNET_Delegates>` + * - :ref:`DisplayDeviceRenderPages<GhostNET_DisplayDeviceRenderPages>` + - Launches a thread rendering a set of pages with the display device. + - :ref:`asynchronous<GhostNET_Delegates>` + * - :ref:`GetStatus<GhostNET_GetStatus>` + - Returns the current status of Ghostscript. + - + * - :ref:`Cancel<GhostNET_Cancel>` + - Cancels asynchronous operations. + - + * - :ref:`GhostscriptException<GhostNET_GhostscriptException>` + - An application developer can log any exceptions in this public class. + - + + +In ``demos/csharp/windows/ghostnet.sln`` there is a sample C# demo project. + +This project can be opened in `Visual Studio`_ and used to test the Ghostscript API alongside a UI which handles opening PostScript and PDF files. The sample application here allows for file browsing and Ghostscript file viewing. + +Below is a screenshot of the sample application with a PDF open: + + +.. note we embedd the image with raw HTML because Sphinx is incapable of doing percentage style widths ... :( + +.. raw:: html + + <img src="_static/ghostnet-wpf-example.png" width=100%/> + + + + +Enums +-------- + + +Tasks +~~~~~~~~~~~~~~~~ + +The Ghostscript task type ``enum`` is used to inform :title:`GhostAPI` of the type of operation which is being requested. + + +.. list-table:: + :header-rows: 1 + + * - Task + - Description + * - ``PS_DISTILL`` + - Task associated with converting a PostScript stream to a PDF document. + * - ``CREATE_XPS`` + - Task associated with outputting a copy of a document to XPS. + * - ``SAVE_RESULT`` + - Task associated with saving documents. + * - ``GET_PAGE_COUNT`` + - Task associated with getting the page count of a document. + * - ``GENERIC`` + - Generic task identifier. + * - ``DISPLAY_DEV_THUMBS`` + - Display Device task associated with rendering thumbnails. + * - ``DISPLAY_DEV_NON_PDF`` + - Display Device task associated with non-PDF or non-XPS rendering (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`). + * - ``DISPLAY_DEV_PDF`` + - Display Device task associated with PDF & XPS rendering (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`). + * - ``DISPLAY_DEV_RUN_FILE`` + - Display Device task associated with running files. + + +Task types are defined as ``GS_Task_t``. + + +.. code-block:: csharp + + public enum GS_Task_t + { + PS_DISTILL, + CREATE_XPS, + SAVE_RESULT, + GET_PAGE_COUNT, + GENERIC, + DISPLAY_DEV_THUMBS, + DISPLAY_DEV_NON_PDF, + DISPLAY_DEV_PDF, + DISPLAY_DEV_RUN_FILE + } + + + + + + + +Results +~~~~~~~~~~~~~~~~ + +Result types are defined as ``GS_Result_t``. + + +.. code-block:: csharp + + public enum GS_Result_t + { + gsOK, + gsFAILED, + gsCANCELLED + } + + +.. _GhostNET_Status: + +Status +~~~~~~~~~~~~~~~~ + +Status types are defined as ``gsStatus``. + + +.. code-block:: csharp + + public enum gsStatus + { + GS_READY, + GS_BUSY, + GS_ERROR + } + + + +The Parameter Struct +------------------------- + +The parameter struct ``gsParamState_t`` allows for bundles of information to be processed by Ghostscript to complete overall requests. + + +.. code-block:: csharp + + public struct gsParamState_t + { + public String outputfile; + public String inputfile; + public GS_Task_t task; + public GS_Result_t result; + public int num_pages; + public List<int> pages; + public int firstpage; + public int lastpage; + public int currpage; + public List<String> args; + public int return_code; + public double zoom; + public bool aa; + public bool is_valid; + }; + + +Parameters explained +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Setting up your parameters (with any dedicated bespoke method(s) which your application requires) is needed when communicating directly with :title:`GhostAPI`. + +When requesting Ghostscript to process an operation an application developer should send a parameter payload which defines the details for the operation. + +For example in :title:`GhostNET` we can see the public method as follows: + + +.. code-block:: csharp + + public gsStatus DistillPS(String fileName, int resolution) + { + gsParamState_t gsparams = new gsParamState_t(); + gsparams.args = new List<string>(); + + gsparams.inputfile = fileName; + gsparams.args.Add("gs"); + gsparams.args.Add("-sDEVICE=pdfwrite"); + gsparams.outputfile = Path.GetTempFileName(); + gsparams.args.Add("-o" + gsparams.outputfile); + gsparams.task = GS_Task_t.PS_DISTILL; + + return RunGhostscriptAsync(gsparams); + } + + + +Here we can see a parameter payload being setup before being passed on to the asynchronous method ``RunGhostscriptAsync`` which sets up a worker thread to run according to the task type in the payload. + +:title:`GhostNET` handles many common operations on an application developer's behalf, however if you require to write your own methods to interface with :title:`GhostAPI` then referring to the public methods in :title:`GhostNET` is a good starting point. + +For full documentation on parameters refer to :ref:`Ghostscript parameters<Use_Setting Parameters>`. + + + + + +The Event class +------------------ + +:title:`GhostNET` contains a public class ``gsEventArgs`` which is an extension of the C# class ``EventArgs``. This class is used to set and get events as they occur. :title:`GhostNET` will create these payloads and deliver them back to the application layer's ``ProgressCallBack`` method asynchronously. + + +.. code-block:: csharp + + public class gsEventArgs : EventArgs + { + private bool m_completed; + private int m_progress; + private gsParamState_t m_param; + public bool Completed + { + get { return m_completed; } + } + public gsParamState_t Params + { + get { return m_param; } + } + public int Progress + { + get { return m_progress; } + } + public gsEventArgs(bool completed, int progress, gsParamState_t param) + { + m_completed = completed; + m_progress = progress; + m_param = param; + } + } + + +GSNET +----------- + +This class should be instantiated as a member variable in your application with callback definitions setup as required. + +Handlers for asynchronous operations can injected by providing your own bespoke callback methods to your instance's ``ProgressCallBack`` function. + + +Sample code +~~~~~~~~~~~~~~~~ + +.. code-block:: csharp + + /* Set up ghostscript with callbacks for system updates */ + m_ghostscript = new GSNET(); + m_ghostscript.ProgressCallBack += new GSNET.Progress(gsProgress); + m_ghostscript.StdIOCallBack += new GSNET.StdIO(gsIO); + m_ghostscript.DLLProblemCallBack += new GSNET.DLLProblem(gsDLL); + m_ghostscript.PageRenderedCallBack += new GSNET.PageRendered(gsPageRendered); + m_ghostscript.DisplayDeviceOpen(); + + /* example callback stubs for asynchronous operations */ + private void gsProgress(gsEventArgs asyncInformation) + { + Console.WriteLine($"gsProgress().progress:{asyncInformation.Progress}"); + + if (asyncInformation.Completed) // task complete + { + // what was the task? + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + Console.WriteLine($"CREATE_XPS.outputfile:"); + Console.WriteLine($"{asyncInformation.Params.result.outputfile}"); + break; + + case GS_Task_t.PS_DISTILL: + Console.WriteLine($"PS_DISTILL.outputfile:"); + Console.WriteLine($"{asyncInformation.Params.result.outputfile}"); + break; + + case GS_Task_t.SAVE_RESULT: + + break; + + case GS_Task_t.DISPLAY_DEV_THUMBS: + + break; + + case GS_Task_t.DISPLAY_DEV_RUN_FILE: + + break; + + case GS_Task_t.DISPLAY_DEV_PDF: + + break; + + case GS_Task_t.DISPLAY_DEV_NON_PDF: + + break; + + default: + + break; + } + + // task failed + if (asyncInformation.Params.result == GS_Result_t.gsFAILED) + { + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + + break; + + case GS_Task_t.PS_DISTILL: + + break; + + case GS_Task_t.SAVE_RESULT: + + break; + + default: + + break; + } + return; + } + + // task cancelled + if (asyncInformation.Params.result == GS_Result_t.gsCANCELLED) + { + + } + } + else // task is still running + { + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + + break; + + case GS_Task_t.PS_DISTILL: + + break; + + case GS_Task_t.SAVE_RESULT: + + break; + } + } + } + + private void gsIO(String message, int len) + { + Console.WriteLine($"gsIO().message:{message}, length:{len}"); + } + + private void gsDLL(String message) + { + Console.WriteLine($"gsDLL().message:{message}"); + } + + private void gsPageRendered(int width, + int height, + int raster, + IntPtr data, + gsParamState_t state) + { + + }; + + +.. note:: + + Once a Ghostscript operation is in progress any defined callback functions will be called as the operation runs up unto completion. These callback methods are essential for your application to interpret activity events and react accordingly. + +An explanation of callbacks and the available public methods within ``GSNET`` are explained below. + + + +.. _GhostNET_Delegates: + +Delegates +~~~~~~~~~~~~~~~ + +To handle *asynchronous* events :title:`GhostNET` has four delegates which define callback methods that an application can assign to. + + + +.. list-table:: + :header-rows: 1 + + * - Callback + - Description + * - ``DLLProblemCallBack`` + - Occurs if there is some issue with the Ghostscript DLL. + * - ``StdIOCallBack`` + - Occurs if Ghostscript outputs something to ``stderr`` or ``stdout``. + * - ``ProgressCallBack`` + - Occurs as Ghostscript makes its way through a file. + * - ``PageRenderedCallBack`` + - Occurs when a page has been rendered and the data from the display device is ready. + + + +``DLLProblemCallBack`` +""""""""""""""""""""""""" + +.. code-block:: csharp + + internal delegate void DLLProblem(String mess); + internal event DLLProblem DLLProblemCallBack; + + +``StdIOCallBack`` +"""""""""""""""""""""" + +.. code-block:: csharp + + internal delegate void StdIO(String mess, + int len); + internal event StdIO StdIOCallBack; + +``ProgressCallBack`` +"""""""""""""""""""""" + + +.. code-block:: csharp + + internal delegate void Progress(gsEventArgs info); + internal event Progress ProgressCallBack; + + +``PageRenderedCallBack`` +"""""""""""""""""""""""""""" + +.. code-block:: csharp + + internal delegate void PageRendered(int width, + int height, + int raster, + IntPtr data, + gsParamState_t state); + internal event PageRendered PageRenderedCallBack; + + + +.. _GhostNET_GetVersion: + + +``GetVersion`` +~~~~~~~~~~~~~~ + +Use this method to get Ghostscript version info as a ``String``. + + +.. code-block:: csharp + + public String GetVersion() + + +**Sample code:** + +.. code-block:: csharp + + String gs_vers = m_ghostscript.GetVersion(); + + +.. note:: + + An exception will be thrown if there is any issue with the Ghostscript DLL. + + + + +.. _GhostNET_DisplayDeviceOpen: + +``DisplayDeviceOpen`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sets up the :ref:`display device<Devices_Display_Devices>` ahead of time. + +.. code-block:: csharp + + public gsParamState_t DisplayDeviceOpen() + + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceOpen(); + + +.. note:: + + Calling this method instantiates Ghostscript and configures the encoding and the callbacks for the display device. + + + +.. _GhostNET_DisplayDeviceClose: + + +``DisplayDeviceClose`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Closes the :ref:`display device<Devices_Display_Devices>` and deletes the instance. + + +.. code-block:: csharp + + public gsParamState_t DisplayDeviceClose() + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceClose(); + + +.. note:: + + Calling this method :ref:`deletes Ghostscript<gsapi_delete_instance>`. + + + +.. _GhostNET_GetPageCount: + + +``GetPageCount`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use this method to get the number of pages in a supplied document. + + +.. code-block:: csharp + + public int GetPageCount(String fileName) + +**Sample code:** + +.. code-block:: csharp + + int page_number = m_ghostscript.GetPageCount("my_document.pdf"); + +.. note:: + + If Ghostscript is unable to determine the page count then this method will return ``-1``. + + +.. _GhostNET_CreateXPS: + +``CreateXPS`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread to create an XPS document for Windows printing. This method is :ref:`asynchronous<GhostNET_Delegates>` and logic should be hooked into your application upon :ref:`GSNET instantiation<GSNET>` to interpret progress. + + +.. code-block:: csharp + + public gsStatus CreateXPS(String fileName, + int resolution, + int num_pages, + double width, + double height, + bool fit_page, + int firstpage, + int lastpage) + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.CreateXPS("my_document.pdf", + 300, + 10, + 1000, + 1000, + true, + 0, + 9); + + +.. _GhostNET_DistillPS: + + +``DistillPS`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering all the pages of a supplied PostScript file to a PDF. + + +.. code-block:: csharp + + public gsStatus DistillPS(String fileName, int resolution) + + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DistillPS("my_postscript_document.ps", 300); + + + +.. _GhostNET_DisplayDeviceRunFile: + + +``DisplayDeviceRunFile`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread to run a file with the :ref:`display device<Devices_Display_Devices>`. + + +.. code-block:: csharp + + public gsStatus DisplayDeviceRunFile(String fileName, + double zoom, + bool aa, // anti-aliasing value + int firstpage, + int lastpage) + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceRunFile("my_document.pdf", + 1.0, + true, + 0, + 9); + + +.. _GhostNET_DisplayDeviceRenderThumbs: + +``DisplayDeviceRenderThumbs`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering all the pages with the :ref:`display device<Devices_Display_Devices>` to collect thumbnail images. + +Recommended zoom level for thumbnails is between 0.05 and 0.2, additionally anti-aliasing is probably not required. + + +.. code-block:: csharp + + public gsStatus DisplayDeviceRenderThumbs(String fileName, + double zoom, + bool aa) + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceRenderThumbs("my_document.pdf", + 0.1, + false); + + + +.. _GhostNET_DisplayDeviceRenderPages: + + +``DisplayDeviceRenderPages`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering a set of pages with the :ref:`display device<Devices_Display_Devices>`. For use with languages that can be indexed via pages which include PDF and XPS. (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`) + + +.. code-block:: csharp + + public gsStatus DisplayDeviceRenderPages(String fileName, + int first_page, + int last_page, + double zoom) + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceRenderPages("my_document.pdf", + 0, + 9, + 1.0); + + +.. _GhostNET_GetStatus: + +``GetStatus`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Returns the current :ref:`status<_GhostNET_Status>` of Ghostscript. + + +.. code-block:: csharp + + public gsStatus GetStatus() + +**Sample code:** + +.. code-block:: csharp + + gsStatus status = m_ghostscript.GetStatus(); + + + +.. _GhostNET_Cancel: + + +``Cancel`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Cancels :ref:`asynchronous<GhostNET_Delegates>` operations. + + +.. code-block:: csharp + + public void Cancel() + + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.Cancel(); + + + +.. _GhostNET_GhostscriptException: + + +``GhostscriptException`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An application developer can log any exceptions in this public class as required by editing the constructor. + + +.. code-block:: csharp + + public class GhostscriptException : Exception + { + public GhostscriptException(string message) : base(message) + { + // Report exceptions as required + } + } + + + + + + + + + + +GhostMono +======================= + +:title:`GhostMono` is the C# interface into the :title:`GhostAPI` library and is developed for Linux systems. + +As such :title:`GhostMono` is the Mono_ equivalent of :title:`GhostNET` with no dependency on a Windows environment. + + + + + + +Enums +-------- + + +Tasks +~~~~~~~~~~~~~~~~ + +The Ghostscript task type ``enum`` is used to inform :title:`GhostAPI` of the type of operation which is being requested. + + +.. list-table:: + :header-rows: 1 + + * - Task + - Description + * - ``PS_DISTILL`` + - Task associated with converting a PostScript stream to a PDF document. + * - ``CREATE_XPS`` + - Task associated with outputting a copy of a document to XPS. + * - ``SAVE_RESULT`` + - Task associated with saving documents. + * - ``GET_PAGE_COUNT`` + - Task associated with getting the page count of a document. + * - ``GENERIC`` + - Generic task identifier. + * - ``DISPLAY_DEV_THUMBS`` + - Display Device task associated with rendering thumbnails. + * - ``DISPLAY_DEV_NON_PDF`` + - Display Device task associated with non-PDF or non-XPS rendering (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`). + * - ``DISPLAY_DEV_PDF`` + - Display Device task associated with PDF & XPS rendering (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`). + * - ``DISPLAY_DEV_RUN_FILE`` + - Display Device task associated with running files. + + +Task types are defined as ``GS_Task_t``. + + +.. code-block:: csharp + + public enum GS_Task_t + { + PS_DISTILL, + CREATE_XPS, + SAVE_RESULT, + GET_PAGE_COUNT, + GENERIC, + DISPLAY_DEV_THUMBS, + DISPLAY_DEV_NON_PDF, + DISPLAY_DEV_PDF, + DISPLAY_DEV_RUN_FILE + } + + + + + + + +Results +~~~~~~~~~~~~~~~~ + +Result types are defined as ``GS_Result_t``. + + +.. code-block:: csharp + + public enum GS_Result_t + { + gsOK, + gsFAILED, + gsCANCELLED + } + + +Status +~~~~~~~~~~~~~~~~ + +Status types are defined as ``gsStatus``. + + +.. code-block:: csharp + + public enum gsStatus + { + GS_READY, + GS_BUSY, + GS_ERROR + } + + + +The Parameter Struct +------------------------- + +The parameter struct ``gsParamState_t`` allows for bundles of information to be processed by Ghostscript to complete overall requests. + + +.. code-block:: csharp + + public struct gsParamState_t + { + public String outputfile; + public String inputfile; + public GS_Task_t task; + public GS_Result_t result; + public int num_pages; + public List<int> pages; + public int firstpage; + public int lastpage; + public int currpage; + public List<String> args; + public int return_code; + public double zoom; + }; + + +Parameters explained +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Setting up your parameters (with any dedicated bespoke method(s) which your application requires) is needed when communicating directly with :title:`GhostAPI`. + +When requesting Ghostscript to process an operation an application developer should send a parameter payload which defines the details for the operation. + +For example in :title:`GhostMono` we can see the public method as follows: + +.. code-block:: csharp + + public gsStatus DistillPS(String fileName, int resolution) + { + gsParamState_t gsparams = new gsParamState_t(); + gsparams.args = new List<string>(); + + gsparams.inputfile = fileName; + gsparams.args.Add("gs"); + gsparams.args.Add("-dNOPAUSE"); + gsparams.args.Add("-dBATCH"); + gsparams.args.Add("-I%rom%Resource/Init/"); + gsparams.args.Add("-dSAFER"); + gsparams.args.Add("-sDEVICE=pdfwrite"); + gsparams.outputfile = Path.GetTempFileName(); + gsparams.args.Add("-o" + gsparams.outputfile); + gsparams.task = GS_Task_t.PS_DISTILL; + + return RunGhostscriptAsync(gsparams); + } + + +Here we can see a parameter payload being setup before being passed on to the asynchronous method ``RunGhostscriptAsync`` which sets up a worker thread to run according to the task type in the payload. + +:title:`GhostMono` handles many common operations on an application developer's behalf, however if you require to write your own methods to interface with :title:`GhostAPI` then referring to the public methods in :title:`GhostMono` is a good starting point. + +For full documentation on parameters refer to :ref:`Ghostscript parameters in C<Use_Setting Parameters>`. + + + + +The Event class +-------------------- + +:title:`GhostMono` contains a public class ``gsThreadCallBack``. This class is used to set and get callback information as they occur. :title:`GhostMono` will create these payloads and deliver them back to the application layer's ``ProgressCallBack`` method asynchronously. + + +.. code-block:: csharp + + public class gsThreadCallBack + { + private bool m_completed; + private int m_progress; + private gsParamState_t m_param; + public bool Completed + { + get { return m_completed; } + } + public gsParamState_t Params + { + get { return m_param; } + } + public int Progress + { + get { return m_progress; } + } + public gsThreadCallBack(bool completed, int progress, gsParamState_t param) + { + m_completed = completed; + m_progress = progress; + m_param = param; + } + } + + +GSMONO +---------- + +This class should be instantiated as a member variable in your application with callback definitions setup as required. + +Handlers for asynchronous operations can injected by providing your own bespoke callback methods to your instance's ``ProgressCallBack`` function. + + +.. code-block:: csharp + + /* Set up Ghostscript with callbacks for system updates */ + m_ghostscript = new GSMONO(); + m_ghostscript.ProgressCallBack += new GSMONO.Progress(gsProgress); + m_ghostscript.StdIOCallBack += new GSMONO.StdIO(gsIO); + m_ghostscript.DLLProblemCallBack += new GSMONO.DLLProblem(gsDLL); + m_ghostscript.PageRenderedCallBack += new GSMONO.PageRendered(gsPageRendered); + m_ghostscript.DisplayDeviceOpen(); + + /* example callback stubs for asynchronous operations */ + private void gsProgress(gsThreadCallBack asyncInformation) + { + Console.WriteLine($"gsProgress().progress:{asyncInformation.Progress}"); + + if (asyncInformation.Completed) // task complete + { + // what was the task? + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + Console.WriteLine($"CREATE_XPS.outputfile:"); + Console.WriteLine($"{asyncInformation.Params.result.outputfile}"); + break; + + case GS_Task_t.PS_DISTILL: + Console.WriteLine($"PS_DISTILL.outputfile:"); + Console.WriteLine($"{asyncInformation.Params.result.outputfile}"); + break; + + case GS_Task_t.SAVE_RESULT: + + break; + + case GS_Task_t.DISPLAY_DEV_THUMBS: + + break; + + case GS_Task_t.DISPLAY_DEV_RUN_FILE: + + break; + + case GS_Task_t.DISPLAY_DEV_PDF: + + break; + + case GS_Task_t.DISPLAY_DEV_NON_PDF: + + break; + + default: + + break; + } + + // task failed + if (asyncInformation.Params.result == GS_Result_t.gsFAILED) + { + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + + break; + + case GS_Task_t.PS_DISTILL: + + break; + + case GS_Task_t.SAVE_RESULT: + + break; + + default: + + break; + } + return; + } + + // task cancelled + if (asyncInformation.Params.result == GS_Result_t.gsCANCELLED) + { + + } + } + else // task is still running + { + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + + break; + + case GS_Task_t.PS_DISTILL: + + break; + + case GS_Task_t.SAVE_RESULT: + + break; + } + } + } + + private void gsIO(String message, int len) + { + Console.WriteLine($"gsIO().message:{message}, length:{len}"); + } + + private void gsDLL(String message) + { + Console.WriteLine($"gsDLL().message:{message}"); + } + + private void gsPageRendered(int width, + int height, + int raster, + IntPtr data, + gsParamState_t state) + { + + }; + + + +.. note:: + + Once a Ghostscript operation is in progress any defined callback functions will be called as the operation runs up unto completion. These callback methods are essential for your application to interpret activity events and react accordingly. + + +An explanation of callbacks and the available public methods within :title:`GSMONO` are explained below. + + + + +Delegates +~~~~~~~~~~~~~~ + +To handle *asynchronous events* :title:`GhostMONO` has four delegates which define callback methods that an application can assign to. + + +.. list-table:: + :header-rows: 1 + + * - Callback + - Description + * - ``DLLProblemCallBack`` + - Occurs if there is some issue with the Ghostscript Shared Object (libgpdl.so) + * - ``StdIOCallBack`` + - Occurs if Ghostscript outputs something to ``stderr`` or ``stdout``. + * - ``ProgressCallBack`` + - Occurs as Ghostscript makes its way through a file. + * - ``PageRenderedCallBack`` + - Occurs when a page has been rendered and the data from the display device is ready. + + + +``DLLProblemCallBack`` +""""""""""""""""""""""""" + +.. code-block:: csharp + + internal delegate void DLLProblem(String mess); + internal event DLLProblem DLLProblemCallBack; + + +``StdIOCallBack`` +"""""""""""""""""""""" + +.. code-block:: csharp + + internal delegate void StdIO(String mess, + int len); + internal event StdIO StdIOCallBack; + +``ProgressCallBack`` +"""""""""""""""""""""" + + +.. code-block:: csharp + + internal delegate void Progress(gsEventArgs info); + internal event Progress ProgressCallBack; + + +``PageRenderedCallBack`` +"""""""""""""""""""""""""""" + +.. code-block:: csharp + + internal delegate void PageRendered(int width, + int height, + int raster, + IntPtr data, + gsParamState_t state); + internal event PageRendered PageRenderedCallBack; + + + + + +``GetVersion`` +~~~~~~~~~~~~~~ + +Use this method to get Ghostscript version info as a ``String``. + + +.. code-block:: csharp + + public String GetVersion() + + +**Sample code:** + +.. code-block:: csharp + + String gs_vers = m_ghostscript.GetVersion(); + + +.. note:: + + An exception will be thrown if there is any issue with the Ghostscript DLL. + + + + + + +``DisplayDeviceOpen`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sets up the :ref:`display device<Devices_Display_Devices>` ahead of time. + +.. code-block:: csharp + + public gsParamState_t DisplayDeviceOpen() + + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceOpen(); + + +.. note:: + + Calling this method instantiates Ghostscript and configures the encoding and the callbacks for the display device. + + + + +``DisplayDeviceClose`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Closes the :ref:`display device<Devices_Display_Devices>` and deletes the instance. + + +.. code-block:: csharp + + public gsParamState_t DisplayDeviceClose() + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceClose(); + + +.. note:: + + Calling this method :ref:`deletes Ghostscript<gsapi_delete_instance>`. + + + + +``GetPageCount`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use this method to get the number of pages in a supplied document. + + +.. code-block:: csharp + + public int GetPageCount(String fileName) + +**Sample code:** + +.. code-block:: csharp + + int page_number = m_ghostscript.GetPageCount("my_document.pdf"); + +.. note:: + + If Ghostscript is unable to determine the page count then this method will return ``-1``. + + + +``DistillPS`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering all the pages of a supplied PostScript file to a PDF. + + +.. code-block:: csharp + + public gsStatus DistillPS(String fileName, int resolution) + + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DistillPS("my_postscript_document.ps", 300); + + + +``DisplayDeviceRenderAll`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering all the document pages with the :ref:`display device<Devices_Display_Devices>`. For use with languages that can be indexed via pages which include PDF and XPS. (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`) + + +.. code-block:: csharp + + public gsStatus DisplayDeviceRenderAll(String fileName, double zoom, bool aa, GS_Task_t task) + + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceRenderAll("my_document.pdf", + 0.1, + false, + GS_Task_t.DISPLAY_DEV_THUMBS_NON_PDF); + + + +``DisplayDeviceRenderThumbs`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering all the pages with the :ref:`display device<Devices_Display_Devices>` to collect thumbnail images. + +Recommended zoom level for thumbnails is between 0.05 and 0.2, additionally anti-aliasing is probably not required. + + +.. code-block:: csharp + + public gsStatus DisplayDeviceRenderThumbs(String fileName, + double zoom, + bool aa) + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceRenderThumbs("my_document.pdf", + 0.1, + false); + + + +``DisplayDeviceRenderPages`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Launches a thread rendering a set of pages with the :ref:`display device<Devices_Display_Devices>`. For use with languages that can be indexed via pages which include PDF and XPS. (see: :ref:`Ghostscript & Page Description Languages<gs_and_PDL>`) + + +.. code-block:: csharp + + public gsStatus DisplayDeviceRenderPages(String fileName, + int first_page, + int last_page, + double zoom) + +**Sample code:** + +.. code-block:: csharp + + m_ghostscript.DisplayDeviceRenderPages("my_document.pdf", + 0, + 9, + 1.0); + + + +``GetStatus`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Returns the current :ref:`status<_GhostNET_Status>` of Ghostscript. + + +.. code-block:: csharp + + public gsStatus GetStatus() + +**Sample code:** + +.. code-block:: csharp + + gsStatus status = m_ghostscript.GetStatus(); + + + +``GhostscriptException`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An application developer can log any exceptions in this public class as required by editing the constructor. + + +.. code-block:: csharp + + public class GhostscriptException : Exception + { + public GhostscriptException(string message) : base(message) + { + // Report exceptions as required + } + } + + + + +.. _gs_and_PDL: + + +.. note:: + + Ghostscript & Page Description Languages + + Ghostscript handles the following `PDLs`_: PCL PDF PS XPS. + + PCL and PS do not allow random access, meaning that, to print page 2 in a 100 page document, Ghostscript has to read the entire document stream of 100 pages. + + On the other hand, PDF and XPS allow for going directly to page 2 and then only dealing with that content. The tasks ``DISPLAY_DEV_NON_PDF`` and ``DISPLAY_DEV_PDF`` keep track of what sort of input Ghostscript is dealing with and enables the application to direct progress or completion callbacks accordingly. + + + + + + + + + + +.. External links + +.. _commercial license: https://artifex.com/licensing/commercial/ +.. _.NET: https://dotnet.microsoft.com/ +.. _Visual Studio: https://visualstudio.microsoft.com/ +.. _Mono: https://www.mono-project.com/ +.. _GhostPDL repository: https://ghostscript.com/releases/gpdldnld.html + + +.. _PDLs: https://en.wikipedia.org/wiki/Page_description_language + diff --git a/doc/src/LanguageBindingsJava.rst b/doc/src/LanguageBindingsJava.rst new file mode 100644 index 00000000..a17d52d2 --- /dev/null +++ b/doc/src/LanguageBindingsJava.rst @@ -0,0 +1,1415 @@ +.. title:: Java + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + + +Introduction +============== + +In the ``GhostPDL`` repository sample Java projects can be found in ``/demos/java``. + +Within this location the following folders are of relevance: + +- :ref:`jni<jni: Building the Java Native Interface>` ``jni`` +- :ref:`gsjava<java gsjava>` ``gsjava`` +- :ref:`gstest<java gstest>` ``gstest`` +- :ref:`gsviewer<java gsviewer>` ``gsviewer`` + + + +Platform & setup +======================= + + +Ghostscript should be built as a shared library for your platform. + +See :ref:`Building Ghostscript<Building Ghostscript>`. + + + +jni: Building the Java Native Interface +-------------------------------------------------- + +Before building the JNI ensure that Ghostscript has already been built for your platform and that you have JDK installed. + +The JNI is for use in the Java interface, this object must be placed somewhere on your Java ``PATH``. On Windows, the DLL can be placed in the working directory, next to ``gsjava.jar``. + + + +.. list-table:: + :header-rows: 1 + + * - Platform + - JNI file + * - Windows + - ``gs_jni.dll`` + * - MacOS + - ``gs_jni.dylib`` + * - Linux / OpenBSD + - ``gs_jni.so`` + + +Preparing your include folder +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The build scripts require the header ``jni.h``, which defines all JNI functions, and ``jni_md.h``, which defines all system-specific integer types. The build scripts expect an include folder relative to their location which contain these header files from your system. + +These headers are typically found in the following directories: + + +.. list-table:: + :header-rows: 1 + + * - Platform + - jni.h + - jni_md.h + * - Windows + - C:\Program Files\Java\<JDK Install>\include\jni.h + - C:\Program Files\Java\<JDK Install>\include\win32\jni_md.h + * - MacOS + - /Library/Java/JavaVirtualMachines/<JDK Install>/Contents/Home/include/jni.h + - /Library/Java/JavaVirtualMachines/<JDK Install>/Contents/Home/include/darwin/jni_md.h + * - Linux + - /lib/jvm/<JDK Install>/include/jni.h + - /lib/jvm/<JDK Install>/include/linux/jni_md.h + + + +Once your ``include`` folder has been located folder you can copy it and place it in your ``ghostpdl/demos/java/jni/gs_jni`` folder. + +Your build scripts should now be ready to run as they will be able to find the required JNI header files in their own relative include folder. + +Building on Windows +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``jni`` folder contains a Visual Studio Solution file ``/jni/gs_jni/gs_jni.sln`` which you should use to build the required JNI ``gs_jni.dll`` library file. + +With the project open in Visual Studio, select the required architecture from the drop down - then right click on 'gs_jni' in the solution explorer and choose "Build". + + +Building on MacOS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On your command line, navigate to ``ghostpdl/demos/java/jni/gs_jni`` and ensure that the build script is executable and then run it, with: + +.. code-block:: bash + + chmod +x build_darwin.sh + ./build_darwin.sh + + +Building on Linux +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On your command line, navigate to ``ghostpdl/demos/java/jni/gs_jni`` and ensure that the build script is executable and then run it, with: + +.. code-block:: bash + + chmod +x build_linux.sh + ./build_linux.sh + + + +gsjava: Building the JAR +--------------------------------- + +``gsjava.jar`` is the Java library which contains classes and interfaces which enable API calls required to use Ghostscript. + +Assuming that the JAR for your project has been built and properly linked with your own project then the Ghostscript API should be available by importing the required classes within your project's ``.java`` files. + + + +Building with the command line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Navigate to ``ghostpdl/demos/java/gsjava`` and use the following: + + +.. list-table:: + :header-rows: 1 + + * - Platform + - Run file + * - Windows + - build_win32.bat + * - MacOS + - build_darwin.sh + * - Linux + - build_linux.sh + +.. note:: + + ``gsjava`` has a dependency on ``jni``, please ensure that :ref:`gs_jni<jni: Building the Java Native Interface>` is able to be built beforehand. + + + +Building with Eclipse +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively you can use Eclipse_ to build the JAR file. + +Using Eclipse_ import the source folder ``gsjava`` as a project and select ``Export > Java > JAR File`` as shown in the screenshot example below: + + +.. note we embedd the image with raw HTML because Sphinx is incapable of doing percentage style widths ... :( + +.. raw:: html + + <img src="_static/export-jar.png" width=70%/> + + + + +Linking the JAR +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The built JAR should be properly linked within your project Java Build Path as follows: + + +.. raw:: html + + <img src="_static/linking-jar.png" width=80%/> + + + +Demo projects +================== + +.. _java gstest: + +gstest +---------------------------------------- + +Use this to quickly test Ghostscript methods. + +This project can be opened in Eclipse and used to test the Ghostscript API. The sample here simply sets up an instance of Ghostscript and then sets and gets some parameters accordingly. + + + +.. _java gsviewer: + +gsviewer +------------------------------------ + +A handy file viewer. + +This project can be used to test the Ghostscript API alongside a UI which handles opening PostScript and PDF files. The sample application here allows for file browsing and Ghostscript file viewing. + +Below is a screenshot of the sample application with a PDF open: + + +.. raw:: html + + <img src="_static/gsviewer.png" width=100%/> + + + +To run the project navigate to the ``demos/java/gsviewer`` location and ensure that the required libraries are in the directory: + + +.. list-table:: + :header-rows: 1 + :widths: 15 70 15 + + * - Platform + - Ghostscript library file + - JNI library file + * - Windows + - ``gpdldll64.dll`` + - ``gs_jni.dll`` + * - MacOS + - ``libgpdl.dylib`` + - ``gs_jni.dylib`` + * - Linux / OpenBSD + - ``libgpdl.so`` (this may have been built as ``libgs.so``, + + so it should be copied into this directory and + + renamed to ``libgpdl.so``) + - ``gs_jni.so`` + + +Building on Windows +~~~~~~~~~~~~~~~~~~~~~~~ + +Run the ``build_win32.bat`` script. + +Running on Windows +~~~~~~~~~~~~~~~~~~~~~~~ + +To run, open ``gsviewer.jar`` either through File Explorer or in the command line through the following command: + + +.. code-block:: bash + + java -jar gsviewer.jar + + +Building on MacOS +~~~~~~~~~~~~~~~~~~~~~~~ + +On your command line, navigate to ``ghostpdl/demos/java/gsviewer`` and ensure that the build script is executable and then run it, with: + +.. code-block:: bash + + chmod +x build_darwin.sh + ./build_darwin.sh + +This will automatically ``build gs_jni.dylib`` (in the ``ghostpdl/demos/java/jni/gs_jni/`` location) and ``gsjava.jar`` ``gsviewer.jar`` in the ``gsviewer`` directory. + + +Running on MacOS +~~~~~~~~~~~~~~~~~~~~~~~ + +Ensure that the Ghostscript library exists in the ``gsviewer`` directory. (Copy and move the built library from ``ghostpdl/sobin`` as required). + +Ensure that the run script is executable and then run it, with: + +.. code-block:: bash + + chmod +x start_darwin.sh + ./start_darwin.sh + + +Building on Linux +~~~~~~~~~~~~~~~~~~~~~~~ + +On your command line, navigate to ``ghostpdl/demos/java/gsviewer`` and ensure that the build script is executable and then run it, with: + +.. code-block:: bash + + chmod +x build_linux.sh + ./build_linux.sh + +This will automatically build ``gs_jni.so`` (in the ``ghostpdl/demos/java/jni/gs_jni/`` location) and ``gsjava.jar`` ``gsviewer.jar`` in the ``gsviewer`` directory. + + +.. note:: + + On Linux, when using OpenJDK, the property "assistive_technologies" may need to be modified for the Java code to build. It can be modified by editing the "accessibility.properties" file. This is located at: + + ``/etc/java-8-openjdk/accessibility.properties`` + + +Running on Linux +~~~~~~~~~~~~~~~~~~~~~~~ + +Ensure that the Ghostscript library exists in the ``gsviewer`` directory. (Copy and move the built library from ``ghostpdl/sobin`` as required). + +Ensure that the run script is executable and then run it, with: + +.. code-block:: bash + + chmod +x start_linux.sh + ./start_linux.sh + + + +.. _java gsjava: + +Using the Java library +================================== + + +gsjava +---------- + +There are two main classes within the ``gsjava.jar`` library to consider: + + +GSAPI & GSInstance +--------------------- + +:title:`GSAPI` is the main Ghostscript API class which bridges into the :ref:`Ghostscript C library<API.htm exported functions>`. + +:title:`GSInstance` is a wrapper class for :title:`GSAPI` which encapsulates an instance of Ghostscript and allows for simpler API calls. + + +**Sample code:** + + +.. code-block:: java + + // to use GSAPI + import static com.artifex.gsjava.GSAPI.*; + + // to use GSInstance + import com.artifex.gsjava.GSInstance; + + +GSAPI +-------- + + +.. _java gsapi_revision: + +``gsapi_revision`` +~~~~~~~~~~~~~~~~~~~~ + +This method returns the revision numbers and strings of the Ghostscript interpreter library; you should call it before any other interpreter library functions to make sure that the correct version of the Ghostscript interpreter has been loaded. + + +.. code-block:: java + + public static native int gsapi_revision(GSAPI.Revision revision, + int len); + +.. note:: + + The method should write to a reference variable which conforms to the class ``GSAPI.Revision``. + +``GSAPI.Revision`` +"""""""""""""""""""""" + +This class is used to store information about Ghostscript and provides handy getters for the product and the copyright information. + + + +.. code-block:: java + + public static class Revision { + public volatile byte[] product; + public volatile byte[] copyright; + public volatile long revision; + public volatile long revisionDate; + + public Revision() { + this.product = null; + this.copyright = null; + this.revision = 0L; + this.revisionDate = 0L; + } + + /** + * Returns the product information as a String. + * + * @return The product information. + */ + public String getProduct() { + return new String(product); + } + + /** + * Returns the copyright information as a String. + * + * @return The copyright information. + */ + public String getCopyright() { + return new String(copyright); + } + } + + +.. _java gsapi_new_instance: + +``gsapi_new_instance`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Creates a new instance of Ghostscript. This instance is passed to most other :title:`GSAPI` methods. Unless Ghostscript has been compiled with the ``GS_THREADSAFE`` define, only one instance at a time is supported. + +.. code-block:: java + + public static native int gsapi_new_instance(Reference<Long> instance, + long callerHandle); + +.. note:: + + The method returns a reference which represents your instance of Ghostscript. + + +.. _java gsapi_delete_instance: + + +``gsapi_delete_instance`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Destroy an instance of Ghostscript. Before you call this, Ghostscript must have finished. If Ghostscript has been initialised, you should call :ref:`gsapi_exit<java gsapi_exit>` beforehand. + + +.. code-block:: java + + public static native void gsapi_delete_instance(long instance); + + + +.. _java gsapi_set_stdio_with_handle: + +``gsapi_set_stdio_with_handle`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback functions for ``stdio``, together with the handle to use in the callback functions. The ``stdin`` callback function should return the number of characters read, ``0`` for ``EOF``, or ``-1`` for ``error``. The ``stdout`` and ``stderr`` callback functions should return the number of characters written. + + +.. code-block:: java + + public static native int gsapi_set_stdio_with_handle(long instance, + IStdInFunction stdin, + IStdOutFunction stdout, + IStdErrFunction stderr, + long callerHandle); + + +.. _java gsapi_set_stdio: + +``gsapi_set_stdio`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback functions for ``stdio``. The handle used in the callbacks will be taken from the value passed to :ref:`gsapi_new_instance<java gsapi_new_instance>`. Otherwise the behaviour of this function matches :ref:`gsapi_set_stdio_with_handle<java gsapi_set_stdio_with_handle>`. + + +.. code-block:: java + + public static native int gsapi_set_stdio(long instance, + IStdInFunction stdin, + IStdOutFunction stdout, + IStdErrFunction stderr); + + + + +.. _java gsapi_set_poll_with_handle: + +``gsapi_set_poll_with_handle`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback function for polling, together with the handle to pass to the callback function. This function will only be called if the Ghostscript interpreter was compiled with ``CHECK_INTERRUPTS`` as described in ``gpcheck.h``. + +The polling function should return zero if all is well, and return negative if it wants Ghostscript to abort. This is often used for checking for a user cancel. This can also be used for handling window events or cooperative multitasking. + +The polling function is called very frequently during interpretation and rendering so it must be fast. If the function is slow, then using a counter to ``return 0`` immediately some number of times can be used to reduce the performance impact. + +.. code-block:: java + + public static native int gsapi_set_poll_with_handle(long instance, + IPollFunction pollfun, + long callerHandle); + + + +.. _java gsapi_set_poll: + +``gsapi_set_poll`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the callback function for polling. The handle passed to the callback function will be taken from the handle passed to :ref:`gsapi_new_instance<java gsapi_new_instance>`. Otherwise the behaviour of this function matches :ref:`gsapi_set_poll_with_handle<java gsapi_set_poll_with_handle>`. + +.. code-block:: java + + public static native int gsapi_set_poll(long instance, + IPollFunction pollfun); + + +.. _java gsapi_set_display_callback: + +``gsapi_set_display_callback`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call is deprecated; please use :ref:`gsapi_register_callout<java gsapi_register_callout>` to register a callout handler for the display device in preference. + + +.. code-block:: java + + public static native int gsapi_set_display_callback(long instance, + DisplayCallback displayCallback); + + +.. _java gsapi_register_callout: + +``gsapi_register_callout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call registers a callout handler. + +.. code-block:: java + + public static native int gsapi_register_callout(long instance, + ICalloutFunction callout, + long calloutHandle); + + +.. _java gsapi_deregister_callout: + +``gsapi_deregister_callout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This call deregisters a callout handler previously registered with :ref:`gsapi_register_callout<java gsapi_register_callout>`. All three arguments must match exactly for the callout handler to be deregistered. + +.. code-block:: java + + public static native void gsapi_deregister_callout(long instance, + ICalloutFunction callout, + long calloutHandle); + + +.. _java gsapi_set_arg_encoding: + +``gsapi_set_arg_encoding`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the encoding used for the interpretation of all subsequent arguments supplied via the GSAPI_ interface on this instance. By default we expect args to be in encoding 0 (the 'local' encoding for this OS). On Windows this means "the currently selected codepage". This means that omitting to call this function will leave Ghostscript running exactly as it always has. Please note that use of the 'local' encoding is now deprecated and should be avoided in new code. This must be called after :ref:`gsapi_new_instance<java gsapi_new_instance>` and before :ref:`gsapi_init_with_args<java gsapi_init_with_args>`. + + +.. code-block:: java + + public static native int gsapi_set_arg_encoding(long instance, + int encoding); + + +.. _java gsapi_set_default_device_list: + +``gsapi_set_default_device_list`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the string containing the list of default device names, for example "display x11alpha x11 bbox". Allows the calling application to influence which device(s) Ghostscript will try, in order, in its selection of the default device. This must be called after :ref:`gsapi_new_instance<java gsapi_new_instance>` and before :ref:`gsapi_init_with_args<java gsapi_init_with_args>`. + + +.. code-block:: java + + public static native int gsapi_set_default_device_list(long instance, + byte[] list, + int listlen); + + +.. _java gsapi_get_default_device_list: + +``gsapi_get_default_device_list`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Returns a pointer to the current default device string. This must be called after :ref:`gsapi_new_instance<java gsapi_new_instance>` and before :ref:`gsapi_init_with_args<java gsapi_init_with_args>`. + + +.. code-block:: java + + public static native int gsapi_get_default_device_list(long instance, + Reference<byte[]> list, + Reference<Integer> listlen); + + +.. _java gsapi_init_with_args: + + +``gsapi_init_with_args`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To initialise the interpreter, pass your ``instance`` of Ghostscript, your argument count: ``argc``, and your argument variables: ``argv``. + + +.. code-block:: java + + public static native int gsapi_init_with_args(long instance, + int argc, + byte[][] argv); + +.. note:: + + There are also simpler utility methods which eliminates the need to send through your argument count and allows for simpler ``String`` passing for your argument array. + + *Utility methods*: + + .. code-block:: java + + public static int gsapi_init_with_args(long instance, + String[] argv); + + public static int gsapi_init_with_args(long instance, + List<String> argv); + + + + +.. _java gsapi_run_asterisk: + +``gsapi_run_*`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If these functions return ``<= -100``, either quit or a fatal error has occured. You must call :ref:`java gsapi_exit<gsapi_exit>` next. The only exception is :ref:`gsapi_run_string_continue<java gsapi_run_string_continue>` which will return ``gs_error_NeedInput`` if all is well. + +There is a 64 KB length limit on any buffer submitted to a ``gsapi_run_*`` function for processing. If you have more than 65535 bytes of input then you must split it into smaller pieces and submit each in a separate :ref:`gsapi_run_string_continue<java gsapi_run_string_continue>` call. + + +.. _java gsapi_run_string_begin: + + +``gsapi_run_string_begin`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. code-block:: java + + public static native int gsapi_run_string_begin(long instance, + int userErrors, + Reference<Integer> pExitCode); + +.. _java gsapi_run_string_continue: + +``gsapi_run_string_continue`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public static native int gsapi_run_string_continue(long instance, + byte[] str, + int length, + int userErrors, + Reference<Integer> pExitCode); + + +.. note:: + + There is a simpler utility method which allows for simpler ``String`` passing for the ``str`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_run_string_continue(long instance, + String str, + int length, + int userErrors, + Reference<Integer> pExitCode); + + +.. _java gsapi_run_string_with_length: + +``gsapi_run_string_with_length`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public static native int gsapi_run_string_with_length(long instance, + byte[] str, + int length, + int userErrors, + Reference<Integer> pExitCode); + +.. note:: + + There is a simpler utility method which allows for simpler ``String`` passing for the ``str`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_run_string_with_length(long instance, + String str, + int length, + int userErrors, + Reference<Integer> pExitCode); + + +.. _java gsapi_run_string: + + +``gsapi_run_string`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public static native int gsapi_run_string(long instance, + byte[] str, + int userErrors, + Reference<Integer> pExitCode); + + +.. note:: + + There is a simpler utility method which allows for simpler ``String`` passing for the ``str`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_run_string(long instance, + String str, + int userErrors, + Reference<Integer> pExitCode); + + +.. _java gsapi_run_string_end: + + +``gsapi_run_string_end`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public static native int gsapi_run_string_end(long instance, + int userErrors, + Reference<Integer> pExitCode); + + +.. _java gsapi_run_file: + +``gsapi_run_file`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public static native int gsapi_run_file(long instance, + byte[] fileName, + int userErrors, + Reference<Integer> pExitCode); + +.. note:: + + There is a simpler utility method which allows for simpler ``String`` passing for the ``fileName`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_run_file(long instance, + String fileName, + int userErrors, + Reference<Integer> pExitCode); + + +.. _java gsapi_exit: + + +``gsapi_exit`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Exit the interpreter. This must be called on shutdown if :ref:`gsapi_init_with_args<java gsapi_init_with_args>` has been called, and just before :ref:`gsapi_delete_instance<java gsapi_delete_instance>`. + +.. code-block:: java + + public static native int gsapi_exit(long instance); + + + +.. _java gsapi_set_param: + +``gsapi_set_param`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sets a parameter. Broadly, this is equivalent to setting a parameter using ``-d``, ``-s`` or ``-p`` on the command line. This call cannot be made during a :ref:`gsapi_run_string<java gsapi_run_string>` operation. + +Parameters in this context are not the same as 'arguments' as processed by :ref:`gsapi_init_with_args<java gsapi_init_with_args>`, but often the same thing can be achieved. For example, with :ref:`gsapi_init_with_args<java gsapi_init_with_args>`, we can pass "-r200" to change the resolution. Broadly the same thing can be achieved by using :ref:`gsapi_set_param<java gsapi_set_param>` to set a parsed value of "<</HWResolution [ 200.0 200.0 ]>>". + +Internally, when we set a parameter, we perform an ``initgraphics`` operation. This means that using :ref:`gsapi_set_param<java gsapi_set_param>` other than at the start of a page is likely to give unexpected results. + +Attempting to set a parameter that the device does not recognise will be silently ignored, and that parameter will not be found in subsequent :ref:`gsapi_get_param<java gsapi_get_param>` calls. + + +.. code-block:: java + + public static native int gsapi_set_param(long instance, + byte[] param, + Object value, + int paramType); + +.. note:: + + For more on the C implementation of parameters see: :ref:`Ghostscript parameters in C<Use_Setting Parameters>`. + + There are also simpler utility methods which allows for simpler String passing for your arguments. + + *Utility methods*: + + + .. code-block:: java + + public static int gsapi_set_param(long instance, + String param, + String value, + int paramType); + + public static int gsapi_set_param(long instance, + String param, + Object value, + int paramType); + + +.. _java gsapi_get_param: + +``gsapi_get_param`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Retrieve the current value of a parameter. + +If an error occurs, the return value is negative. Otherwise the return value is the number of bytes required for storage of the value. Call once with value ``NULL`` to get the number of bytes required, then call again with value pointing to at least the required number of bytes where the value will be copied out. Note that the caller is required to know the type of value in order to get it. For all types other than ``gs_spt_string``, ``gs_spt_name``, and ``gs_spt_parsed`` knowing the type means you already know the size required. + +This call retrieves parameters/values that have made it to the device. Thus, any values set using ``gs_spt_more_to_come`` without a following call omitting that flag will not be retrieved. Similarly, attempting to get a parameter before :ref:`gsapi_init_with_args<java gsapi_init_with_args>` has been called will not list any, even if :ref:`gsapi_set_param<java gsapi_set_param>` has been used. + +Attempting to read a parameter that is not set will return ``gs_error_undefined`` (-21). Note that calling :ref:`gsapi_set_param<java gsapi_set_param>` followed by :ref:`gsapi_get_param<java gsapi_get_param>` may not find the value, if the device did not recognise the key as being one of its configuration keys. + +For further documentation please refer to :ref:`the C API<API_gsapi_get_param>`. + + +.. code-block:: java + + public static native int gsapi_get_param(long instance, + byte[] param, + long value, + int paramType); +.. note:: + + There is a simpler utility method which allows for simpler ``String`` passing for the ``param`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_get_param(long instance, + String param, + long value, + int paramType); + + +.. _java gsapi_enumerate_params: + +``gsapi_enumerate_params`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enumerate the current parameters. Call repeatedly to list out the current parameters. + +The first call should have ``iter = NULL``. Subsequent calls should pass the same pointer in so the iterator can be updated. Negative return codes indicate error, 0 success, and 1 indicates that there are no more keys to read. On success, key will be updated to point to a null terminated string with the key name that is guaranteed to be valid until the next call to :ref:`gsapi_enumerate_params<java gsapi_enumerate_params>`. If type is non ``NULL`` then the pointer type will be updated to have the type of the parameter. + +.. note:: + + Only one enumeration can happen at a time. Starting a second enumeration will reset the first. + +The enumeration only returns parameters/values that have made it to the device. Thus, any values set using the ``gs_spt_more_to_come`` without a following call omitting that flag will not be retrieved. Similarly, attempting to enumerate parameters before :ref:`gsapi_init_with_args<java gsapi_init_with_args>` has been called will not list any, even if :ref:`gsapi_set_param<java gsapi_set_param>` has been used. + + +.. code-block:: java + + public static native int gsapi_enumerate_params(long instance, + Reference<Long> iter, + Reference<byte[]> key, + Reference<Integer> paramType); + + +.. _java gsapi_add_control_path: + +``gsapi_add_control_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add a (case sensitive) path to one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + +.. code-block:: java + + public static native int gsapi_add_control_path(long instance, + int type, + byte[] path); + +.. note:: + There is a simpler utility method which allows for simpler ``String`` passing for the ``path`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_add_control_path(long instance, + int type, + String path); + + + +.. _java gsapi_remove_control_path: + +``gsapi_remove_control_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Remove a (case sensitive) path from one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + +.. code-block:: java + + public static native int gsapi_remove_control_path(long instance, + int type, + byte[] path); +.. note:: + + There is a simpler utility method which allows for simpler ``String`` passing for the ``path`` argument. + + *Utility method*: + + .. code-block:: java + + public static int gsapi_remove_control_path(long instance, + int type, + String path); + + + +.. _java gsapi_purge_control_paths: + +``gsapi_purge_control_paths`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Clear all the paths from one of the lists of :ref:`permitted paths<Use Safer>` for file access. + +.. code-block:: java + + public static native void gsapi_purge_control_paths(long instance, + int type); + + +.. _java gsapi_activate_path_control: + +``gsapi_activate_path_control`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enable/Disable path control (i.e. whether paths are checked against :ref:`permitted paths<Use Safer>` before access is granted). + +.. code-block:: java + + public static native void gsapi_activate_path_control(long instance, + boolean enable); + + +.. _java gsapi_is_path_control_active: + + +``gsapi_is_path_control_active`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Query whether path control is activated or not. + + +.. code-block:: java + + public static native boolean gsapi_is_path_control_active(long instance); + + + +Callback & Callout interfaces +-------------------------------------- + +``gsjava.jar`` also defines some functional interfaces for callbacks & callouts with package ``com.artifex.gsjava.callback`` which are defined as follows. + + +``IStdInFunction`` +~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public interface IStdInFunction { + /** + * @param callerHandle The caller handle. + * @param buf A string represented by a byte array. + * @param len The number of bytes to read. + * @return The number of bytes read, must be <code>len</code>/ + */ + public int onStdIn(long callerHandle, + byte[] buf, + int len); + } + + +``IStdOutFunction`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public interface IStdOutFunction { + /** + * Called when something should be written to the standard + * output stream. + * + * @param callerHandle The caller handle. + * @param str The string represented by a byte array to write. + * @param len The number of bytes to write. + * @return The number of bytes written, must be <code>len</code>. + */ + public int onStdOut(long callerHandle, + byte[] str, + int len); + } + + +``IStdErrFunction`` +~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public interface IStdErrFunction { + /** + * Called when something should be written to the standard error stream. + * + * @param callerHandle The caller handle. + * @param str The string represented by a byte array to write. + * @param len The length of bytes to be written. + * @return The amount of bytes written, must be <code>len</code>. + */ + public int onStdErr(long callerHandle, + byte[] str, + int len); + } + + +``IPollFunction`` +~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public interface IPollFunction { + public int onPoll(long callerHandle); + } + + +``ICalloutFunction`` +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public interface ICalloutFunction { + public int onCallout(long instance, + long calloutHandle, + byte[] deviceName, + int id, + int size, + long data); + } + + + +GSInstance +--------------- + +This is a utility class which makes Ghostscript calls easier by storing a Ghostscript instance and, optionally, a caller handle. Essentially the class acts as a handy wrapper for the standard GSAPI_ methods. + + +Constructors +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: java + + public GSInstance() throws IllegalStateException; + public GSInstance(long callerHandle) throws IllegalStateException; + + +``delete_instance`` +~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_delete_instance<java gsapi_delete_instance>`. + +.. code-block:: java + + public void delete_instance(); + + +``set_stdio`` +~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_set_stdio<java gsapi_set_stdio>`. + +.. code-block:: java + + public int set_stdio(IStdInFunction stdin, + IStdOutFunction stdout, + IStdErrFunction stderr); + +``set_poll`` +~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_set_poll<java gsapi_set_poll>`. + +.. code-block:: java + + public int set_poll(IPollFunction pollfun); + + +``set_display_callback`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_set_display_callback<java gsapi_set_display_callback>`. + +.. code-block:: java + + public int set_display_callback(DisplayCallback displaycallback); + + +``register_callout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_register_callout<java gsapi_register_callout>`. + +.. code-block:: java + + public int register_callout(ICalloutFunction callout); + + +``deregister_callout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_deregister_callout<java gsapi_deregister_callout>`. + +.. code-block:: java + + public void deregister_callout(ICalloutFunction callout); + + +``set_arg_encoding`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_set_arg_encoding<java gsapi_set_arg_encoding>`. + +.. code-block:: java + + public int set_arg_encoding(int encoding); + + +``set_default_device_list`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_set_default_device_list<java gsapi_set_default_device_list>`. + +.. code-block:: java + + public int set_default_device_list(byte[] list, + int listlen); + + +``get_default_device_list`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Wraps :ref:`gsapi_get_default_device_list<java gsapi_get_default_device_list>`. + +.. code-block:: java + + public int get_default_device_list(Reference<byte[]> list, + Reference<Integer> listlen); + +``init_with_args`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_init_with_args<java gsapi_init_with_args>`. + +.. code-block:: java + + public int init_with_args(int argc, + byte[][] argv); + + public int init_with_args(String[] argv); + + public int init_with_args(List<String> argv); + + + +``run_string_begin`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_run_string_begin<java gsapi_run_string_begin>`. + +.. code-block:: java + + public int run_string_begin(int userErrors, + Reference<Integer> pExitCode); + +``run_string_continue`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_run_string_continue<java gsapi_run_string_continue>`. + +.. code-block:: java + + public int run_string_continue(byte[] str, + int length, + int userErrors, + Reference<Integer> pExitCode); + + public int run_string_continue(String str, + int length, + int userErrors, + Reference<Integer> pExitCode); + + +``run_string`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_run_string<java gsapi_run_string>`. + + +.. code-block:: java + + public int run_string(byte[] str, + int userErrors, + Reference<Integer> pExitCode); + + public int run_string(String str, + int userErrors, + Reference<Integer> pExitCode); + + +``run_file`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_run_file<java gsapi_run_file>`. + + +.. code-block:: java + + public int run_file(byte[] fileName, + int userErrors, + Reference<Integer> pExitCode); + + public int run_file(String filename, + int userErrors, + Reference<Integer> pExitCode); + + +``exit`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_exit<java gsapi_exit>`. + +.. code-block:: java + + public int exit(); + + +``set_param`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_set_param<java gsapi_set_param>`. + +.. code-block:: java + + public int set_param(byte[] param, + Object value, + int paramType); + + public int set_param(String param, + String value, + int paramType); + + public int set_param(String param, + Object value, + int paramType); + + +``get_param`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_get_param<java gsapi_get_param>`. + + +.. code-block:: java + + public int get_param(byte[] param, + long value, + int paramType); + + public int get_param(String param, + long value, + int paramType); + +``enumerate_params`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_enumerate_params<java gsapi_enumerate_params>`. + +.. code-block:: java + + public int enumerate_params(Reference<Long> iter, + Reference<byte[]> key, + Reference<Integer> paramType); + + + +``add_control_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_add_control_path<java gsapi_add_control_path>`. + + +.. code-block:: java + + public int add_control_path(int type, + byte[] path); + + public int add_control_path(int type, + String path); + + +``remove_control_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_remove_control_path<java gsapi_remove_control_path>`. + + +.. code-block:: java + + public int remove_control_path(int type, + byte[] path); + + public int remove_control_path(int type, + String path); + +``purge_control_paths`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_purge_control_paths<java gsapi_purge_control_paths>`. + + +.. code-block:: java + + public void purge_control_paths(int type); + + +``activate_path_control`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_activate_path_control<java gsapi_activate_path_control>`. + +.. code-block:: java + + public void activate_path_control(boolean enable); + + +``is_path_control_active`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wraps :ref:`gsapi_is_path_control_active<java gsapi_is_path_control_active>`. + +.. code-block:: java + + public boolean is_path_control_active(); + + +Utility classes +------------------ + +The ``com.artifex.gsjava.util`` package contains a set of classes and interfaces which are used throughout the API. + +``com.artifex.gsjava.util.Reference`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``Reference<T>`` is used in many of the Ghostscript calls, it stores a reference to a generic value of type ``T``. This class exists to emulate pointers being passed to a native function. Its value can be fetched with ``getValue()`` and set with ``setValue(T value)``. + + +.. code-block:: java + + public class Reference<T> { + + private volatile T value; + + public Reference() { + this(null); + } + + public Reference(T value) { + this.value = value; + } + + public void setValue(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + ... + } + +.. External links + +.. _Eclipse: https://www.eclipse.org/eclipseide/ diff --git a/doc/src/LanguageBindingsPython.rst b/doc/src/LanguageBindingsPython.rst new file mode 100644 index 00000000..6330dc17 --- /dev/null +++ b/doc/src/LanguageBindingsPython.rst @@ -0,0 +1,969 @@ +.. title:: Python + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + + +Introduction +================= + +The Python API is provided by the file :ref:`gsapi.py<python gsapi>` - this is the binding to the :ref:`Ghostscript C library<API.htm exported functions>`. + +In the :title:`GhostPDL` repository sample Python examples can be found in ``/demos/python/examples.py``. + + +Platform & setup +======================= + + +Ghostscript should be built as a shared library for your platform. + +See :ref:`Building Ghostscript<Building Ghostscript>`. + + + +Specifying the Ghostscript shared library +------------------------------------------------- + +Two environmental variables can be used to specify where to find the Ghostscript shared library. + +``GSAPI_LIB`` sets the exact path of the Ghostscript shared library, otherwise, ``GSAPI_LIBDIR`` sets the directory containing the Ghostscript shared library. + +If neither is defined we will use the OS's default location(s) for shared libraries. + +If ``GSAPI_LIB`` is not defined, the leafname of the shared library is inferred from the OS type: + + +.. list-table:: + :header-rows: 1 + + * - Platform + - Shared library file + * - Windows + - ``gsdll64.dll`` + * - MacOS + - ``libgs.dylib`` + * - Linux / OpenBSD + - ``libgs.so`` + + +API test +------------ + +The ``gsapi.py`` file that provides the Python bindings can also be used to test the bindings, by running it directly. + +Assuming that your Ghostscript library has successfully been created, then from the root of your ``ghostpdl`` repository checkout do the following: + + +**Windows** + + + Run ``gsapi.py`` as a test script in a ``cmd.exe`` window: + + .. code-block:: bash + + set GSAPI_LIBDIR=debugbin&& python ./demos/python/gsapi.py + + + Run ``gsapi.py`` as a test script in a ``PowerShell`` window: + + .. code-block:: bash + + cmd /C "set GSAPI_LIBDIR=debugbin&& python ./demos/python/gsapi.py" + + +**Linux/OpenBSD/MacOS** + + + Run ``gsapi.py`` as a test script: + + .. code-block:: bash + + GSAPI_LIBDIR=sodebugbin ./demos/python/gsapi.py + + +.. note:: + + If there are no errors then this will have validated that the Ghostscript library is present & operational. + + +.. _python gsapi: + + +The gsapi Python module +===================================== + +Assuming that the above platform & setup has been completed, then ``gsapi`` should be imported into your own Python scripts for API usage. + + +- Implemented using Python's ``ctypes`` module. + +- All functions have the same name as the C function that they wrap. + +- Functions raise a ``GSError`` exception if the underlying function returned a negative error code. + +- Functions that don't have out-params return ``None``. Out-params are returned directly (using tuples if there are more than one). + + + +.. _python gsapi_revision: + + +``gsapi_revision()`` +--------------------------------------------------------------- + +Returns a ``gsapi_revision_t``. + +This method returns the revision numbers and strings of the Ghostscript interpreter library; you should call it before any other interpreter library functions to make sure that the correct version of the Ghostscript interpreter has been loaded. + + +**Sample code**: + +.. code-block:: python + + version_info = gsapi.gsapi_revision() + print(version_info) + + +**C code reference**: :ref:`gsapi_revision<API.htm gsapi_revision>` + + + +.. _python gsapi_new_instance: + + +``gsapi_new_instance(caller_handle)`` +--------------------------------------------------------------- + + +Returns a new instance of Ghostscript to be used with other :ref:`gsapi_*()<python gsapi_run_asterisk>` functions. + + +**Parameters:** + +``caller_handle`` + Typically unused, but is passed to callbacks e.g. via :ref:`gsapi_set_stdio()<python gsapi_set_stdio>`. Must be convertible to a ``C void*``, so ``None`` or an ``integer`` is ok but other types such as strings will fail. + + +**Sample code**: + +.. code-block:: python + + instance = gsapi.gsapi_new_instance(1) + + +**C code reference**: :ref:`gsapi_new_instance<API.htm gsapi_new_instance>` + + +.. _python gsapi_delete_instance: + + +``gsapi_delete_instance(instance)`` +--------------------------------------------------------------- + +Destroy an instance of Ghostscript. Before you call this, Ghostscript should ensure to have finished any processes. + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_delete_instance(instance) + + +**C code reference**: :ref:`gsapi_delete_instance<API.htm gsapi_delete_instance>` + +.. _python gsapi_set_stdio: + + +``gsapi_set_stdio(instance, stdin_fn, stdout_fn, stderr_fn)`` +--------------------------------------------------------------- + +Set the callback functions for ``stdio``, together with the handle to use in the callback functions. + + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``stdin_fn`` + If not ``None``, will be called with: + + - ``(caller_handle, text, len_)``: + - ``caller_handle``: As passed originally to ``gsapi_new_instance()``. + - ``text``: A ``ctypes.LP_c_char`` of length ``len_``. + + +``stdout_fn`` , ``stderr_fn`` + If not ``None``, called with: + + - ``(caller_handle, text)``: + - ``caller_handle``: As passed originally to ``gsapi_new_instance()``. + - ``text``: A Python bytes object. + + +Should return the number of bytes of text that they handled; for convenience ``None`` is converted to ``len(text)``. + + +**Sample code**: + +.. code-block:: python + + def stdout_fn(caller_handle, bytes_): + sys.stdout.write(bytes_.decode('latin-1')) + + gsapi.gsapi_set_stdio(instance, None, stdout_fn, None) + print('gsapi_set_stdio() ok.') + + +**C code reference**: :ref:`gsapi_set_stdio<API.htm gsapi_set_stdio>` + +.. _python gsapi_set_poll: + +``gsapi_set_poll(instance, poll_fn)`` +--------------------------------------------------------------- + +Set the callback function for polling. + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``poll_fn`` + Will be called with ``caller_handle`` as passed to :ref:`gsapi_new_instance(python gsapi_new_instance)<>`. + + +**Sample code**: + +.. code-block:: python + + def poll_fn(caller_handle, bytes_): + sys.stdout.write(bytes_.decode('latin-1')) + + gsapi.gsapi_set_poll(instance, poll_fn) + print('gsapi_set_poll() ok.') + + +**C code reference**: :ref:`gsapi_set_poll<API.htm gsapi_set_poll>` + +.. _python gsapi_set_display_callback: + +``gsapi_set_display_callback(instance, callback)`` +--------------------------------------------------------------- + +Sets the display callback. + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``callback`` + Must be a ``display_callback`` instance. + +**Sample code**: + +.. code-block:: python + + d = display_callback() + gsapi.gsapi_set_display_callback(instance, d) + print('gsapi_set_display_callback() ok.') + + +**C code reference**: :ref:`gsapi_set_display_callback<API.htm gsapi_set_display_callback>` + +.. _python gsapi_set_arg_encoding: + +``gsapi_set_arg_encoding(instance, encoding)`` +--------------------------------------------------------------- + +Set the encoding used for the interpretation of all subsequent arguments supplied via the :title:`GhostAPI` interface on this instance. By default we expect args to be in encoding ``0`` (the 'local' encoding for this OS). On Windows this means "the currently selected codepage". On Linux this typically means utf8. This means that omitting to call this function will leave Ghostscript running exactly as it always has. + +This must be called after :ref:`gsapi_new_instance<python gsapi_new_instance>` and before :ref:`gsapi_init_with_args<python gsapi_init_with_args>`. + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``encoding`` + Encoding must be one of: + + .. list-table:: + :header-rows: 1 + + * - Encoding enum + - Value + * - ``GS_ARG_ENCODING_LOCAL`` + - 0 + * - ``GS_ARG_ENCODING_UTF8`` + - 1 + * - ``GS_ARG_ENCODING_UTF16LE`` + - 2 + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_set_arg_encoding(instance, gsapi.GS_ARG_ENCODING_UTF8) + + +.. note:: + + Please note that use of the 'local' encoding (``GS_ARG_ENCODING_LOCAL``) is now deprecated and should be avoided in new code. + + + +**C code reference**: :ref:`gsapi_set_arg_encoding<API.htm gsapi_set_arg_encoding>` + + +.. _python gsapi_set_default_device_list: + +``gsapi_set_default_device_list(instance, list_)`` +--------------------------------------------------------------- + +Set the string containing the list of default device names, for example "display x11alpha x11 bbox". Allows the calling application to influence which device(s) Ghostscript will try, in order, in its selection of the default device. This must be called after :ref:`gsapi_new_instance<python gsapi_new_instance>` and before :ref:`gsapi_init_with_args<python gsapi_init_with_args>`. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``list_`` + A string of device names. + + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_set_default_device_list(instance, 'bmp256 bmp32b bmpgray cdeskjet cdj1600 cdj500') + + + +**C code reference**: :ref:`gsapi_set_default_device_list<API.htm gsapi_set_default_device_list>` + + +.. _python gsapi_get_default_device_list: + +``gsapi_get_default_device_list(instance)`` +--------------------------------------------------------------- + +Returns a string containing the list of default device names. This must be called after :ref:`gsapi_new_instance<python gsapi_new_instance>` and before :ref:`gsapi_init_with_args<python gsapi_init_with_args>`. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + + +**Sample code**: + +.. code-block:: python + + device_list = gsapi.gsapi_get_default_device_list(instance) + print(device_list) + + +**C code reference**: :ref:`gsapi_get_default_device_list<API.htm gsapi_get_default_device_list>` + + +.. _python gsapi_init_with_args: + +``gsapi_init_with_args(instance, args)`` +--------------------------------------------------------------- + +To initialise the interpreter, pass your ``instance`` of Ghostscript and your argument variables with ``args``. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``args`` + A list/tuple of strings. + + +**Sample code**: + +.. code-block:: python + + in_filename = 'tiger.eps' + out_filename = 'tiger.pdf' + params = ['gs', '-dNOPAUSE', '-dBATCH', '-sDEVICE=pdfwrite', + '-o', out_filename, '-f', in_filename] + gsapi.gsapi_init_with_args(instance, params) + +**C code reference**: :ref:`gsapi_init_with_args<API.htm gsapi_init_with_args>` + +.. _python gsapi_run_asterisk: + +``gsapi_run_*`` +--------------------------------------------------------------- + +There is a 64 KB length limit on any buffer submitted to a :ref:`gsapi_run_*<python gsapi_run_asterisk>` function for processing. If you have more than 65535 bytes of input then you must split it into smaller pieces and submit each in a separate :ref:`gsapi_run_string_continue<python gsapi_run_string_continue>` call. + +On success (underlying C function's return value is ``>=0``), these functions return the underlying C function's ``exit_code`` out-parameter (and the return value is discarded). Otherwise they raise a ``GSError`` in the usual way (and the underlying ``exit_code`` out-parameter is discarded). + +For full details on these return codes please see :ref:`The C API return codes<API_Return codes>`. + + +.. _User errors parameter explained: + + +.. note:: + + **User errors parameter explained** + + The ``user_errors`` argument is normally set to zero to indicate that errors should be handled through the normal mechanisms within the interpreted code. If set to a negative value, the functions will return an error code directly to the caller, bypassing the interpreted language. The interpreted language's error handler is bypassed, regardless of ``user_errors`` parameter, for the ``gs_error_interrupt`` generated when the polling callback returns a negative value. A positive ``user_errors`` is treated the same as zero. + + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + +.. _python gsapi_run_string_begin: + +``gsapi_run_string_begin(instance, user_errors)`` +--------------------------------------------------------------- + +Starts a ``run_string_`` operation. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``user_errors`` + An ``int``, for more see: `User errors parameter explained`_. + +**Sample code**: + +.. code-block:: python + + exitcode = gsapi.gsapi_run_string_begin(instance, 0) + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + + +.. _python gsapi_run_string_continue: + + +``gsapi_run_string_continue(instance, str_, user_errors)`` +--------------------------------------------------------------- + +Processes file byte data (``str_``) to feed as chunks into Ghostscript. This method should typically be called within a buffer context. + +.. note:: + + An exception is not raised for the ``gs_error_NeedInput`` return code. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``str_`` + Should be either a Python string or a bytes object. If the former, it is converted into a bytes object using utf-8 encoding. + +``user_errors`` + An ``int``, for more see: `User errors parameter explained`_. + + +**Sample code**: + +.. code-block:: python + + exitcode = gsapi.gsapi_run_string_continue(instance, data, 0) + + +.. note:: + + For the return code, we don't raise an exception for ``gs_error_NeedInput``. + + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + + +.. _python gsapi_run_string_with_length: + + +``gsapi_run_string_with_length(instance, str_, length, user_errors)`` +------------------------------------------------------------------------------------------------------------------------------ + +Processes file byte data (``str_``) to feed into Ghostscript when the length is known and the file byte data is immediately available. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``str_`` + Should be either a Python string or a bytes object. If the former, it is converted into a bytes object using utf-8 encoding. + +``length`` + An ``int`` representing the length of ``str_``. + +``user_errors`` + An ``int``, for more see: `User errors parameter explained`_. + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_run_string_with_length(instance,"hello",5,0) + + +.. note:: + + If using this method then ensure that the file byte data will fit into a single (<64k) buffer. + + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + + +.. _python gsapi_run_string: + + +``gsapi_run_string(instance, str_, user_errors)`` +--------------------------------------------------------------- + +Processes file byte data (``str_``) to feed into Ghostscript. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``str_`` + Should be either a Python string or a bytes object. If the former, it is converted into a bytes object using utf-8 encoding. + +``user_errors`` + An ``int``, for more see: `User errors parameter explained`_. + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_run_string(instance,"hello",0) + +.. note:: + + This method can only work on a standard, null terminated C string. + + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + + +.. _python gsapi_run_string_end: + + +``gsapi_run_string_end(instance, user_errors)`` +--------------------------------------------------------------- + +Ends a ``run_string_`` operation. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``user_errors`` + An ``int``, for more see: `User errors parameter explained`_. + + + +**Sample code**: + +.. code-block:: python + + exitcode = gsapi.gsapi_run_string_end(instance, 0) + + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + +.. _python gsapi_run_file: + + +``gsapi_run_file(instance, filename, user_errors)`` +--------------------------------------------------------------- + +Runs a file through Ghostscript. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``filename`` + String representing file name. + +``user_errors`` + An ``int``, for more see: `User errors parameter explained`_. + +**Sample code**: + +.. code-block:: python + + in_filename = 'tiger.eps' + gsapi.gsapi_run_file(instance, in_filename, 0) + + +.. note:: + + This will process the supplied input file with any previously supplied argument parameters. + + +**C code reference**: :ref:`gsapi_run_*<API.htm gsapi_run_asterisk>` + + +.. _python gsapi_exit: + +``gsapi_exit(instance)`` +--------------------------------------------------------------- + +Returns a successful exit code ``0``, or raises a ``GSError`` exception on error. + + +Exit the interpreter. This must be called on shutdown if :ref:`gsapi_init_with_args<python gsapi_init_with_args>` has been called, and just before :ref:`gsapi_delete_instance<python gsapi_delete_instance>`. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_exit(instance) + + + +**C code reference**: :ref:`gsapi_exit<API.htm gsapi_exit>` + + +.. _python gsapi_set_param: + +``gsapi_set_param(instance, param, value, type_=None)`` +--------------------------------------------------------------- + +Sets a parameter. + +We behave much like the underlying ``gsapi_set_param()`` C function, except that we also support automatic inference of type ``type_`` arg by looking at the type of ``value``. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``param`` + Name of parameter, either a ``bytes`` or a ``str``; if ``str`` it is encoded using ``latin-1``. + +``value`` + A ``bool``, ``int``, ``float``, ``bytes`` or ``str``. If ``str``, it is encoded into a ``bytes`` using ``utf-8``. + +``type_`` + If ``type_`` is not ``None``, ``value`` must be convertible to the Python type implied by ``type_``: + + + .. list-table:: + :header-rows: 1 + + * - ``type_`` + - Python type(s) + * - ``gs_spt_null`` + - [Ignored] + * - ``gs_spt_bool`` + - bool + * - ``gs_spt_int`` + - int + * - ``gs_spt_float`` + - float + * - ``gs_spt_name`` + - [Error] + * - ``gs_spt_string`` + - (bytes, str) + * - ``gs_spt_long`` + - int + * - ``gs_spt_i64`` + - int + * - ``gs_spt_size_t`` + - int + * - ``gs_spt_parsed`` + - (bytes, str) + * - ``gs_spt_more_to_come`` + - (bytes, str) + + An exception is raised if ``type_`` is an integer type and ``value`` is outside its range. + + If ``type_`` is ``None``, we choose something suitable for type of ``value``: + + .. list-table:: + :header-rows: 1 + + * - Python type of ``value`` + - ``type_`` + * - bool + - ``gs_spt_bool`` + * - int + - ``gs_spt_i64`` + * - float + - ``gs_spt_float`` + * - bytes + - ``gs_spt_parsed`` + * - str + - ``gs_spt_parsed`` (encoded with utf-8) + + + If value is ``None``, we use ``gs_spt_null``. + + Otherwise ``type_`` must be a ``gs_spt_*`` except for ``gs_spt_invalid`` and ``gs_spt_name`` (we don't allow ``psapi_spt_name`` because the underlying C does not copy the string, so cannot be safely used from Python). + + + +**Sample code**: + +.. code-block:: python + + set_margins = gsapi.gsapi_set_param(instance, "Margins", "[10 10]") + + + +**C code reference**: :ref:`gsapi_set_param<API.htm gsapi_set_param>` + + +.. _python gsapi_get_param: + +``gsapi_get_param(instance, param, type_=None, encoding=None)`` +------------------------------------------------------------------------------------------------------------------------------ + +Returns value of specified parameter, or ``None`` if parameter ``type`` is ``gs_spt_null``. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``param`` + Name of parameter, either a ``bytes`` or ``str``; if a ``str`` it is encoded using ``latin-1``. + +``type_`` + A ``gs_spt_*`` constant or ``None``. If ``None`` we try each ``gs_spt_*`` until one succeeds; if none succeeds we raise the last error. + +``encoding`` + Only affects string values. If ``None`` we return a ``bytes`` object, otherwise it should be the encoding to use to decode into a string, e.g. 'utf-8'. + + +**Sample code**: + +.. code-block:: python + + get_margins = gsapi.gsapi_get_param(instance, "Margins") + + +**C code reference**: :ref:`gsapi_get_param<API.htm gsapi_get_param>` + +.. _python gsapi_enumerate_params: + + +``gsapi_enumerate_params(instance)`` +--------------------------------------------------------------- + +Enumerate the current parameters on the instance of Ghostscript. + +Yields ``(key, value)`` for each ``param``. ``key`` is decoded as ``latin-1``. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + + +**Sample code**: + +.. code-block:: python + + for param, type_ in gsapi.gsapi_enumerate_params(instance): + val = gsapi.gsapi_get_param(instance,param, encoding='utf-8') + print('%-24s : %s' % (param, val)) + + +**C code reference**: :ref:`gsapi_enumerate_params<API.htm gsapi_enumerate_params>` + +.. _python gsapi_add_control_path: + +``gsapi_add_control_path(instance, type_, path)`` +--------------------------------------------------------------- + +Add a (case sensitive) path to one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``type_`` + An ``int`` which must be one of: + + .. list-table:: + :header-rows: 1 + + * - Enum + - Value + * - ``GS_PERMIT_FILE_READING`` + - 0 + * - ``GS_PERMIT_FILE_WRITING`` + - 1 + * - ``GS_PERMIT_FILE_CONTROL`` + - 2 + +``path`` + A string representing the file path. + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_add_control_path(instance, gsapi.GS_PERMIT_FILE_READING, "/docs/secure/") + + +**C code reference**: :ref:`gsapi_add_control_path<API.htm gsapi_add_control_path>` + + +.. _python gsapi_remove_control_path: + + +``gsapi_remove_control_path(instance, type_, path)`` +--------------------------------------------------------------- + +Remove a (case sensitive) path from one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``type_`` + An int representing the permission type. + +``path`` + A string representing the file path. + + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_remove_control_path(instance, gsapi.GS_PERMIT_FILE_READING, "/docs/secure/") + + +**C code reference**: :ref:`gsapi_remove_control_path<API.htm gsapi_remove_control_path>` + +.. _python gsapi_purge_control_paths: + +``gsapi_purge_control_paths(instance, type_)`` +--------------------------------------------------------------- + + +Clear all the paths from one of the lists of :ref:`permitted paths<Use Safer>` for file access. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``type_`` + An ``int`` representing the permission type. + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_purge_control_paths(instance, gsapi.GS_PERMIT_FILE_READING) + + +**C code reference**: :ref:`gsapi_purge_control_paths<API.htm gsapi_purge_control_paths>` + + +.. _python gsapi_activate_path_control: + +``gsapi_activate_path_control(instance, enable)`` +--------------------------------------------------------------- + +Enable/Disable path control (i.e. whether paths are checked against :ref:`permitted paths<Use Safer>` before access is granted). + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + +``enable`` + ``bool`` to enable/disable path control. + + +**Sample code**: + +.. code-block:: python + + gsapi.gsapi_activate_path_control(instance, true) + + + +**C code reference**: :ref:`gsapi_activate_path_control<API.htm gsapi_activate_path_control>` + +.. _python gsapi_is_path_control_active: + + +``gsapi_is_path_control_active(instance)`` +--------------------------------------------------------------- + +Query whether path control is activated or not. + + +**Parameters:** + +``instance`` + Your instance of Ghostscript. + + +**Sample code**: + +.. code-block:: python + + isActive = gsapi.gsapi_is_path_control_active(instance) + + +**C code reference**: :ref:`gsapi_is_path_control_active<API.htm gsapi_is_path_control_active>` + + + + + + diff --git a/doc/src/Lib.rst b/doc/src/Lib.rst new file mode 100644 index 00000000..9ad84080 --- /dev/null +++ b/doc/src/Lib.rst @@ -0,0 +1,607 @@ +.. title:: The Ghostscript Library + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Lib.htm: + + +The Ghostscript Library +=================================== + + + + + +This document describes the Ghostscript library, a set of procedures to implement the graphics and filtering capabilities that are primitive operations in the PostScript language and in Adobe Portable Document Format (PDF). + +Ghostscript is actually two programs: a language interpreter, and a graphics library. The library provides, in the form of C procedures, all the graphics functions of the language, that is, approximately those facilities listed in section 8.1 of the PostScript Language Reference Manual, starting with the graphics state operators. In addition, the library provides some lower-level graphics facilities that offer higher performance in exchange for less generality. + + + +PostScript operator API +-------------------------------------- + +The highest level of the library, which is the one that most clients will use, directly implements the PostScript graphics operators with procedures named ``gs_XXX``, for instance ``gs_moveto`` and ``gs_fill``. Nearly all of these procedures take graphics state objects as their first arguments, such as: + +.. code-block:: bash + + int gs_moveto(gs_state *, double, double); + +Nearly every procedure returns an integer code which is ``>= 0`` for a successful return or ``<0`` for a failure. The failure codes correspond directly to PostScript errors, and are defined in ``gserrors.h``. + +The library implements all the operators in the following sections of the PostScript Language Reference Manual, with the indicated omissions and with the APIs defined in the indicated ``.h`` files. A header of the form ``A.h``(``B.h``) indicates that ``A.h`` is included in ``B.h``, so ``A.h`` need not be included explicitly if ``B.h`` is included. Operators marked with * in the "omissions" column are not implemented directly; the library provides lower-level procedures that can be used to implement the operator. + +There are slight differences in the operators that return multiple values, since C's provisions for this are awkward. Also, the control structure for the operators involving callback procedures (``pathforall``, ``image``, ``colorimage``, ``imagemask``) is partly inverted: the client calls a procedure to set up an enumerator object, and then calls another procedure for each iteration. The ``...show`` operators, ``charpath``, and ``stringwidth`` also use an inverted control structure. + + + + +.. list-table:: + :widths: 30 30 40 + :header-rows: 1 + + * - Section (operators) + - Headers + - Omissions + * - Graphics state – device-independent + - ``gscolor.h`` (``gsstate.h``) + + ``gscolor1.h`` + + ``gscolor2.h`` + + ``gscspace.h`` + + ``gshsb.h`` + + ``gsline.h`` (``gsstate.h``) + + ``gsstate.h`` + + - + * - Graphics state – device-dependent + - ``gscolor.h`` (``gsstate.h``) + + ``gscolor1.h`` + + ``gscolor2.h`` + + ``gsht.h`` (``gsht1.h``, ``gsstate.h``) + + ``gsht1.h`` + + ``gsline.h`` (``gsstate.h``) + + - + * - Coordinate system and matrix + + - ``gscoord.h`` + + ``gsmatrix.h`` + - ``*matrix``, ``*identmatrix``, ``*concatmatrix``, ``*invertmatrix`` + + * - Path construction + + - ``gspath.h`` + + ``gspath2.h`` + - ``*arct``, ``*pathforall``, ``ustrokepath``, ``uappend``, ``upath``, ``ucache`` + + * - Painting + + - ``gsimage.h`` + + ``gspaint.h`` + + ``gspath2.h`` + - ``*image``, ``*colorimage``, ``*imagemask``, ``ufill``, ``ueofill``, ``ustroke`` + + * - Form and pattern + - ``gscolor2.h`` + - ``execform`` + + * - Device setup and output + - ``gsdevice.h`` + - ``*showpage``, ``*set/currentpagedevice`` + * - Character and font + + + - ``gschar.h`` + + ``gsfont.h`` + - ``*`` (all the ``show`` operators), ``definefont``, ``undefinefont``, + + ``findfont``, ``*scalefont``, ``*makefont``, ``selectfont``, + + ``[Global]FontDirectory``, ``Standard/ISOLatin1Encoding``, ``findencoding`` + + + +The following procedures from the list above operate differently from their PostScript operator counterparts, as explained here: + +``gs_makepattern`` (``gscolor2.h``) + Takes an explicit current color, rather than using the current color in the graphics state. Takes an explicit allocator for allocating the pattern implementation. See below for more details on gs_makepattern. + +``gs_setpattern`` (``gscolor2.h``), ``gs_setcolor`` (``gscolor2.h``), ``gs_currentcolor`` (``gscolor2.h``) + Use ``gs_client_color`` rather than a set of color parameter values. See below for more details on ``gs_setpattern``. + +``gs_currentdash_length/pattern/offset`` (``gsline.h``) + Splits up ``currentdash`` into three separate procedures. + +``gs_screen_init/currentpoint/next/install`` (``gsht.h``) + Provide an "enumeration style" interface to ``setscreen``. (``gs_setscreen`` is also implemented.) + +``gs_rotate/scale/translate`` (``gscoord.h``), ``gs_[i][d]transform`` (``gscoord.h``) + These always operate on the graphics state CTM. The corresponding operations on free-standing matrices are in ``gsmatrix.h`` and have different names. + +``gs_path_enum_alloc/init/next/cleanup`` (``gspath.h``) + Provide an "enumeration style" implementation of ``pathforall``. + +``gs_image_enum_alloc`` (``gsimage.h``), ``gs_image_init/next/cleanup`` (``gsimage.h``) + Provide an "enumeration style" interface to the equivalent of ``image``, ``imagemask``, and ``colorimage``. In the ``gs_image_t``, ``ColorSpace`` provides an explicit color space, rather than using the current color space in the graphics state; ``ImageMask`` distinguishes ``imagemask`` from ``[color]image``. + +``gs_get/putdeviceparams`` (``gsdevice.h``) + Take a ``gs_param_list`` for specifying or receiving the parameter values. See ``gsparam.h`` for more details. + +``gs_show_enum_alloc/release`` (``gschar.h``), ``gs_xxxshow_[n_]init`` (``gschar.h``), ``gs_show_next`` (``gschar.h``) + Provide an "enumeration style" interface to writing text. Note that control returns to the caller if the character must be rasterized. + + +This level of the library also implements the following operators from other sections of the Manual: + + + +.. list-table:: + :widths: 30 20 50 + :header-rows: 1 + + * - Section (operators) + - Headers + - Operators + * - Interpreter parameter + - ``gsfont.h`` + - ``cachestatus``, ``setcachelimit``, ``*set/currentcacheparams`` + * - Display PostScript + - ``gsstate.h`` + - ``set/currenthalftonephase`` + + + +In order to obtain the full PostScript Level 2 functionality listed above, ``FEATURE_DEVS`` must be set in the ``makefile`` to include at least the following: + + +.. code-block::bash + + FEATURE_DEVS=patcore.dev cmykcore.dev psl2core.dev dps2core.dev ciecore.dev path1core.dev hsbcore.dev + +The ``*lib.mak`` makefiles mentioned below do not always include all of these features. + +Files named ``gs*.c`` implement the higher level of the graphics library. As might be expected, all procedures, variables, and structures available at this level begin with "``gs_``". Structures that appear in these interfaces, but whose definitions may be hidden from clients, also have names beginning with "``gs_``", that is, the prefix, not the implementation, reflects at what level the abstraction is made available. + + +Patterns +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Patterns are the most complicated PostScript language objects that the library API deals with. As in PostScript, defining a pattern color and using the color are two separate operations. + +``gs_makepattern`` defines a pattern color. Its arguments are as follows: + +.. list-table:: + :widths: 25 75 + :header-rows: 0 + + * - ``gs_client_color *`` + - The resulting ``Pattern`` color is stored here. + + This is different from PostScript, which has no color objects per se, + + and hence returns a modified copy of the dictionary. + + * - ``const gs_client_pattern *`` + - The analogue of the original Pattern dictionary, described in detail just below. + + * - ``const gs_matrix *`` + - Corresponds to the matrix argument of the ``makepattern`` operator. + + * - ``gs_state *`` + - The current graphics state. + + * - ``gs_memory_t *`` + - The allocator to use for allocating the saved data for the Pattern color. + + If this is ``NULL``, ``gs_makepattern`` uses the same allocator that allocated + + the graphics state. Library clients should probably always use ``NULL``. + + +The ``gs_client_pattern`` structure defined in ``gscolor2.h`` corresponds to the ``Pattern`` dictionary that is the argument to the PostScript language ``makepattern`` operator. This structure has one extra member, ``void *client_data``, which is a place for clients to store a pointer to additional data for the ``PaintProc``; this provides the same functionality as putting additional keys in the ``Pattern`` dictionary at the PostScript language level. The ``PaintProc`` is an ordinary C procedure that takes as parameters a ``gs_client_color *``, which is the ``Pattern`` color that is being used for painting, and a ``gs_state *``, which is the same graphics state that would be presented to the ``PaintProc`` in PostScript. Currently the ``gs_client_color *`` is always the current color in the graphics state, but the ``PaintProc`` should not rely on this. The ``PaintProc`` can retrieve the ``gs_client_pattern *`` from the ``gs_client_color *`` with the ``gs_getpattern`` procedure, also defined in ``gscolor2.h``, and from there, it can retrieve the ``client_data`` pointer. + + +The normal way to set a ``Pattern`` color is to call ``gs_setpattern`` with the graphics state and with the ``gs_client_color`` returned by ``gs_makepattern``. After that, one can use ``gs_setcolor`` to set further ``Pattern`` colors (colored, or uncolored with the same underlying color space); the rules are the same as those in PostScript. Note that for ``gs_setpattern``, the ``paint.values`` in the ``gs_client_color`` must be filled in for uncolored patterns; this corresponds to the additional arguments for the PostScript ``setpattern`` operator in the uncolored case. + +There is a special procedure ``gs_makebitmappattern`` for creating bitmap-based patterns. Its API is documented in ``gscolor2.h``; its implementation, in ``gspcolor.c``, may be useful as an example of a pattern using a particularly simple ``PaintProc``. + + +Lower-level API +~~~~~~~~~~~~~~~~~~~~~~~~ + +Files named ``gx*.c`` implement the lower level of the graphics library. The interfaces at the ``gx`` level are less stable, and expose more of the implementation detail, than those at the ``gs`` level: in particular, the ``gx`` interfaces generally use device coordinates in an internal fixed-point representation, as opposed to the ``gs`` interfaces that use floating point user coordinates. Named entities at this level begin with ``gx_``. + +Files named ``gz*.c`` and ``gz*.h`` are internal to the Ghostscript implementation, and are not designed to be called by clients. + +.. _Lib_VisualTrace: + + +Visual Trace instructions +----------------------------- + +Visual Trace instructions may be inserted in code to provide debug output in a graphical form. Graphics Library doesn't provide a rasterisation of the output, because it is platform dependent. Instead this, client application shpuld set ``vd_trace0`` external variable to Graphics Library, passing a set of callbacks which provide the rasterization. + +Visual Trace instructions are defined in ``vdtrace.h``. Debug output must be opened with ``vd_get_dc`` instruction, which obtains a drawing context for the debug output, and must be closed with ``vd_release_dc`` instruction. After opening the output, scale, origin and shift to be set for mapping the debugee coordinate space to window coordinate space. Than painting instructions to be used. Painting may be either immediate or indirect. + +Indirect painting uses ``vd_beg_path`` before line output and ``vd_end_path`` after line output, to store a path into a temporary storage. After this ``vd_stroke`` may be used for stroking the path, or ``vd_fill`` may be used for filling the region inside the path. + +Immediate painting happens when path construction instructions are involved without ``vd_beg_path`` and ``vd_end_path``. In this case lines and curves are being drawed immediately, when a path construction instruction is executed. + +The following table explains the semantics of Visual Trace instructions. + + +Visual Trace instructions semantics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + + * - Instruction + - Function + - Parameters + * - ``vd_get_dc`` + - Obtain drawing context + - ``-T`` option flag value, for which the subsequent output is enabled. + * - ``vd_release_dc`` + - Release drawing context + - + * - ``vd_enabled`` + - Is trace currently enabled ? + - + * - ``vd_get_size_unscaled_x`` + - Get the horizontal size of the output window in pixels. + - + * - ``vd_get_size_unscaled_y`` + - Get the vertical size of the output window in pixels. + - + * - ``vd_get_size_caled_x`` + - Get the horizontal size of the output window in debuggee coordinate units. + - + * - ``vd_get_size_caled_y`` + - Get the vertical size of the output window in debuggee coordinate units. + - + * - ``vd_get_scale_x`` + - Get the horizontal scale. + - + * - ``vd_get_scale_y`` + - Get the vertical scale. + - + * - ``vd_get_origin_x`` + - Get the horizontal position of the draft origin in debuggee coordinate space. + - + * - ``vd_get_origin_y`` + - Get the vertical position of the draft origin in debuggee coordinate space. + - + * - ``vd_set_scale(s)`` + - Set isotripic scale. + - Debugee space to window space mapping scale, same for both dimentions. + * - ``vd_set_scaleXY(sx,sy)`` + - Set anisotripic scale. + - Debugee space to window space mapping scale, one for each dimention. + * - ``vd_set_origin(x,y)`` + - Set the draft origin. + - Origin of the draft in debugee space. + * - ``vd_set_shift(x,y)`` + - Set the draft position. + - Position of the draft origin in window space (in pixels). + * - ``vd_set_central_shift`` + - Set the draft position to window center. + - + * - ``vd_erase(c)`` + - Fill entire window. + - Color to fill. + * - ``vd_beg_path`` + - Begin path construction. + - + * - ``vd_end_path`` + - End path construction. + - + * - ``vd_moveto(x,y)`` + - Path construction : Set the draft current point. + - Debugee coordinates. + * - ``vd_lineto(x,y)`` + - Path construction : Line from current point to specified point. + - Debugee coordinates. + * - ``vd_lineto_mupti(p,n)`` + - Path construction : Polyline from current point to specified points. + - Array of points and its size, debugee coordinates. + * - ``vd_curveto(x0,y0,x1,y1,x2,y2)`` + - Path construction : Curve (3rd-order Bezier) from current point to + + specified point, with specified poles. + - 2 poles and the curve ending point, debuggee coordinates. + * - ``vd_closepath`` + - Path construction : Close the path (is necessary for filling an area). + - + * - ``vd_bar(x0,y0,x1,y1,w,c)`` + - Bar from point to point. + - 2 points (debugee coordinates), width (in pixels) and color. + * - ``vd_square(x0,y0,w,c)`` + - Square with specified center and size. + - The center (debugee coordinates), size (in pixels) and color. + * - ``vd_rect(x0,y0,x1,y1,w,c)`` + - Canonic rectangle with specified coordinites. + - Coordinates of boundaries (debugee coordinates), + + line width (in pixels) and color. + * - ``vd_quad(x0,y0,x1,y1,x2,y2,x3,y3,w,c)`` + - Quadrangle with specified coordinites. + - Coordinates of vertices (debugee coordinates), + + line width (in pixels) and color. + * - ``vd_curve(x0,y0,x1,y1,x2,y2,x3,y3,c,w)`` + - Curve with width. + - 4 curve poles (debugee coordinates), color, and width (in pixels). + * - ``vd_circle(x,y,r,c)`` + - Circle. + - Center (debugee coordinates), radius (in pixels) and color. + * - ``vd_round(x,y,r,c)`` + - Filled circle. + - Center (debugee coordinates), radius (in pixels) and color. + * - ``vd_stroke`` + - Stroke a path constructed with: + + ``vd_beg_path``, ``vd_moveto``, ``vd_lineto``, + + ``vd_curveto``, ``vd_closepath``, ``vd_end_path``. + - + * - ``vd_fill`` + - Fill a path constructed with: + + ``vd_beg_path``, ``vd_moveto``, ``vd_lineto``, + + ``vd_curveto``, ``vd_closepath``, ``vd_end_path``. + - + * - ``vd_setcolor(c)`` + - Set a color. + - Color (an integer consisting of red, green, blue bytes). + * - ``vd_setlinewidth(w)`` + - Set line width. + - Width (in pixels). + * - ``vd_text(x,y,s,c)`` + - Paint a text. + - Origin point (debugee coordinates), a string, and a color. + * - ``vd_wait`` + - Delay execution until a resuming command is entered through user interface. + - + + +Graphics Library doesn't provide a rasterization of the debug output. Instead it calls callbacks, which are specified by a client, and which may have a platform dependent implementation. The implementation must not use Graphics Library to exclude recursive calls to it from Visual Trace instructions. The callbacks and auxiliary data are collected in the structure ``vd_trace_interface``, explained in the table below. + + + + +vd_trace_interface structure +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + + * - Field + - Purpose + - Parameters + * - ``host`` + - A pointer to the rasterizer control block - + + to be provided by client application. + + The type of the field is client dependent. + - + * - ``scale_x``, ``scale_y`` + - Scale of debugee coordinate to window coordinate mapping - + + internal work data, don't change. + - + * - ``orig_x``, ``orig_y`` + - Draft origin in debugee coordinates - + + internal work data, don't change. + - + * - ``shift_x``, ``shift_y`` + - Draft shift in window coordinates - + + internal work data, don't change. + - + * - ``get_size_x(I)`` + - Get window width in pixels. + - + * - ``get_size_y(I)`` + - Get window height in pixels. + - + * - ``get_dc(I,I1)`` + - Obtain drawing context. + - Pointer to interface block, + + and pointer to copy of the pointer. + + Implementation must set ``*I1`` if it succeeds + + to get a drawing context. + * - ``release_dc(I,I1)`` + - Release drawing context. + - Pointer to interface block, + + and pointer to copy of the pointer. + + Implementation must reset ``*I1`` if it succeeds + + to release the drawing context. + * - ``erase(I,c)`` + - Erase entire window. + - Background color. + * - ``beg_path(I)`` + - Begin path construction. + - + * - ``end_path(I)`` + - End path construction. + - + * - ``moveto(I,x,y)`` + - Set current point. + - A point in window coordinates. + * - ``lineto(I,x,y)`` + - Line from current point to specified point. + - A point in window coordinates. + * - ``curveto(I,x0,y0,x1,y1,x2,y2)`` + - Curve from current point with specified + + poles to specified point. + - 3 points in window coordinates. + * - ``closepath(I)`` + - Close the path. + - + * - ``circle(I,x,y,r)`` + - Circle. + - Center and radius, window coordinates. + * - ``round(I,x,y,r)`` + - Filled circle. + - Center and radius, window coordinates. + * - ``fill(I)`` + - Fill the path. + - + * - ``stroke(I)`` + - Stroke the path. + - + * - ``setcolor(I,c)`` + - Set color. + - An integer, consisting of red, green, blue bytes. + * - ``setlinewidth(I,w)`` + - Set line width. + - Line width in pixels. + * - ``text(I,x,y,s)`` + - Draw a text. + - Coordinates in pixels, and a string. + * - ``wait(I)`` + - Delay execution until resume command is + + inputted from user. + - + + + +A full example +----------------------- + +The file ``gslib.c`` in the Ghostscript fileset is a complete example program that initializes the library and produces output using it; files named ``*lib.mak`` (such as ``ugcclib.mak`` and ``bclib.mak``) are ``makefiles`` using ``gslib.c`` as the main program. The following annotated excerpts from this file are intended to provide a roadmap for applications that call the library. + + +.. code-block:: c + + /* Capture stdin/out/err before gs.h redefines them. */ + #include <stdio.h> + static FILE *real_stdin, *real_stdout, *real_stderr; + static void + get_real(void) + { real_stdin = stdin, real_stdout = stdout, real_stderr = stderr; + } + +Any application using Ghostscript should include the fragment above at the very beginning of the main program. + +.. code-block:: c + + #include "gx.h" + +The ``gx.h`` header includes a wealth of declarations related to the Ghostscript memory manager, portability machinery, debugging framework, and other substrate facilities. Any application file that calls any Ghostscript API functions should probably include ``gx.h``. + + +.. code-block:: c + + /* Configuration information imported from gconfig.c. */ + extern gx_device *gx_device_list[]; + + /* Other imported procedures */ + /* from gsinit.c */ + extern void gs_lib_init(P1(FILE *)); + extern void gs_lib_finit(P2(int, int)); + /* from gsalloc.c */ + extern gs_ref_memory_t *ialloc_alloc_state(P2(gs_memory_t *, uint)); + + +The externs above are needed for initializing the library. + +.. code-block:: c + + gs_ref_memory_t *imem; + #define mem ((gs_memory_t *)imem) + gs_state *pgs; + gx_device *dev = gx_device_list[0]; + + gp_init(); + get_real(); + gs_stdin = real_stdin; + gs_stdout = real_stdout; + gs_stderr = real_stderr; + gs_lib_init(stdout); + .... + imem = ialloc_alloc_state(&gs_memory_default, 20000); + imem->space = 0; + .... + pgs = gs_state_alloc(mem); + + +The code above initializes the library and its memory manager. ``pgs`` now points to the graphics state that will be passed to the drawing routines in the library. + +.. code-block:: c + + gs_setdevice_no_erase(pgs, dev); /* can't erase yet */ + { gs_point dpi; + gs_screen_halftone ht; + gs_dtransform(pgs, 72.0, 72.0, &dpi); + ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001; + ht.angle = 0; + ht.spot_function = odsf; + gs_setscreen(pgs, &ht); + } + +The code above initializes the default device and sets a default halftone screen. (For brevity, we have omitted the definition of ``odsf``, the spot function.) + +.. code-block:: c + + /* gsave and grestore (among other places) assume that */ + /* there are at least 2 gstates on the graphics stack. */ + /* Ensure that now. */ + gs_gsave(pgs); + + +The call above completes initializing the graphics state. When the program is finished, it should execute: + +.. code-block:: c + + gs_lib_finit(0, 0); + + + + + + + + +.. include:: footer.rst + + + + + + + + + + diff --git a/doc/src/Make.rst b/doc/src/Make.rst new file mode 100644 index 00000000..db3386d7 --- /dev/null +++ b/doc/src/Make.rst @@ -0,0 +1,1031 @@ +.. title:: How to Build Ghostscript from Source Code + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + + +.. _Make.htm: + +How to Build Ghostscript from Source Code +========================================= + + + + + +General overview +------------------------ + +This document describes how to build a Ghostscript executable from source code. There are four major steps to building Ghostscript: + +#. Acquire the compressed archive files of source code for Ghostscript. + +#. Unpack the archive files into the Ghostscript directory. + +#. Configure the build to match your system and desired configuration options. + +#. Invoke "make" to build the software. + + +The remainder of this document describes each of these steps in detail. Note that some of this process is platform-dependent. After building Ghostscript you must then install it; for that, see the :ref:`installation instructions<Install.htm>`. + +Long term users of Ghostscript may notice the instructions for a number of older systems have been removed from this document. There is no value judgment implied in this, but recognition that the build system has changed considerably in recent years, and several of these legacy systems are no longer easily available to the development team. We will always consider contributions to continue support for legacy systems. + + + +Built libraries +------------------- + +The following Ghostscript libraries will be built for these respective platforms: + +.. list-table:: + :header-rows: 1 + + * - Platform + - Ghostscript library files + * - Windows 32-bit + - ``gpdldll32.dll`` ``gsdll32.dll`` + * - Windows 64-bit + - ``gpdldll64.dll`` ``gsdll64.dll`` + * - MacOS + - ``libgpdl.dylib`` ``libgs.dylib`` + * - Linux / OpenBSD + - ``libgpdl.so`` ``libgs.so`` + + +.. note:: + + The actual filenames on MacOS will be appended with the version of Ghostscript with associated symlinks. + + + +How to acquire the source code +------------------------------------------------ + +Building Ghostscript requires the Ghostscript source code itself, and in some cases the source code for the third-party libraries that Ghostscript uses. + +Official releases can be found under the AGPL license at: + +https://ghostscript.com/download/ + +Ghostscript source code is packaged in gzip-compressed tar archives (``*.tar.gz``), e.g.: + +``ghostscript-#.##.tar.gz`` + +("#.##" are version numbers.) + +Software to decompress and extract both formats is available for almost every platform for which Ghostscript is available -- including Unix, Linux, MS Windows, and so on -- but it's up to you to locate that software. See the section on :ref:`unpacking the source code<Unpack>`. + + +.. note:: + + Unlike earlier versions, Ghostscript packages are now one, complete archive, including font files and third party library dependency sources. + + +.. _Acquiring: + + +How to acquire the development source code +------------------------------------------------------------------------------------------------ + +The Ghostscript team use git_ for version control. + +If you require a snapshot of the development code, the easiest way to get it is to visit the web interface to our git repository: `ghostpdl.git`_ and click the "snapshot" link next to the specific commit in which you are interested. After a short delay, that will download a complete source tree for the given commit in a gzipped tar archive. + +If you require access to several commits, or wish to regularly access the latest development code, you are better to clone the entire git repository, using: + +.. code-block:: bash + + git clone git://git.ghostscript.com/ghostpdl.git + +which will create a local, read-only repository. + +Both the "snapshot" and the git clone methods download the Ghostscript sources as part of the GhostPDL source tree, which includes the PCL/PXL and XPS interpreters also built on top of the Ghostscript graphics library. + +The configure script discussed later in the document is created as part of the Ghostscript release process, and as the source tree retrieved from git is "pre-release" code, it does not include a pre-made configure script. See :ref:`autogen.sh<autogen_sh>`. + + +.. _Unpack: + +How to unpack the source code +------------------------------------------------------------------------------------------------ + +Unfortunately, there are no generally accepted standards for how to package source code into archives, so the instructions for unpacking Ghostscript are longer than they should be. We begin with a brief explanation of how to extract the two kinds of archive files. + + + +.. _TarFiles: + +How to unpack compressed tar files generally +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tar (``.tar``) files are the *de facto* standard for archiving files on Unix (every Unix-like system has the ``tar`` program), and programs to extract their contents are also widely available for MS Windows, and most other environments. To economize on space and downloading time, Ghostscript's tar files are compressed with ``GNU gzip``, which adds the suffix "``.gz``" to the file name, giving "``.tar.gz``". + +To unpack a compressed tar file ``MyArchive.tar.gz`` you must both decompress it and extract the contents. You can do this in two steps, one to decompress the file and another to unpack it: + + +.. code-block:: bash + + gzip -d MyArchive.tar.gz + tar -xf MyArchive.tar + +or in a pipeline: + +.. code-block:: bash + + gzip -d -c MyArchive.tar.gz | tar -xf - + +or, if you have a program like GNU tar that can handle compressed tar files, with a single command: + + +.. code-block:: bash + + tar -zxf MyArchive.tar.gz + + +The ``tar`` program automatically preserves directory structure in extracting files. The Ghostscript source archive puts all files under a directory ``ghostscript-#.##``, so using tar to unpack a compressed archive should always properly create that directory, which we will call the "ghostscript directory". + +Some other programs – under MS Windows, for instance – can also unpack compressed tar files, but they may not automatically preserve directory structure nor even extract files into the current directory. If you use one of these, you must: + +- set the program's options to "Use folder names" (or the equivalent). + +, and: + +- check that it is extracting files into the right place. + +As both ``tar`` and ``gzip`` formats are now well supported by several applications on MS Windows, we only supply the ``tar.gz`` archive. + + +WinZip_, `7-zip`_ & `Info-ZIP`_ are respectively a commercial and two free applications which can decompress and extract ``.tar.gz`` archives on MS Windows. + + + +How to unpack Ghostscript itself +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +At this point you have :ref:`acquired the source code<Acquiring>` and are ready to unpack it according to the :ref:`preceding guidelines<TarFiles>`. + +2-step: + +.. code-block:: bash + + gzip -d ghostscript-#.##.tar.gz + tar -xf ghostscript-#.##.tar + + +Pipe: + +.. code-block:: bash + + gzip -d -c ghostscript-#.##.tar.gz | tar -xf - + +GNU tar: + +.. code-block:: bash + + tar -zxf ghostscript-#.##.tar.gz + + +All the Ghostscript source files are now in subdirectories of the ``ghostscript-#.##`` directory. + + + +Ghostscript Core Source subdirectories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + .. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Subdirectory + - Contents + * - ``arch/`` + - Pre-defined architecture header files + * - ``base/`` + - Graphics library C source code and ``makefiles`` + * - ``contrib/`` + - Community contributed/supported output devices + * - ``devices/`` + - The output devices supported by the Ghostscript team + * - ``psi/`` + - PS interpreter C source code and makefiles + * - ``Resource/`` + - Postscript initialization, resource and font files + * - ``lib/`` + - PostScript utilities and scripts used with Ghostscript + * - ``doc/`` + - Documentation + * - ``man/`` + - Unix man pages + * - ``examples/`` + - Sample PostScript files + * - ``iccprofiles/`` + - Default set of ICC profiles + * - ``windows/`` + - Visual Studio for Windows specific project and solution files + * - ``toolbin/`` + - Useful (non-Postscript) tools, mostly for developer use only + + + +Optionally, if you downloaded the GhostPDL archive, you may also have: + +Additional GhostPDL source subdirectories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + .. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Subdirectory + - Contents + * - ``pcl/`` + - PCL/PXL interpreter C source code, makefiles, fonts etc. + * - ``xps/`` + - XPS interpreter C source code and makefiles + + +Supporting third party libraries will also be in their own sub-directories (e.g. jpeg, freetype and so on). + + + + +How to check for post-release bug fixes +--------------------------------------------- + +Bug information and fixes are tracked on `Ghostscript Bugzilla`_. + + + +.. _Make_MakeFilesOverview: + +How to prepare the ``makefiles`` +--------------------------------------------- + +The Ghostscript ``makefiles`` are very large and complex in order to deal with the diverse requirements of all the different systems where they may be used. + +Ghostscript has an automatic configuration script. If you're on unix or a system that supports unix shell scripts, this is the easiest option to use. Simply type: + + +.. code-block:: bash + + ./configure + +from the top level of the Ghostscript source directory. It should configure itself based on what's available on your system, warn you of any missing dependencies, and generate a ``Makefile``. At this point you can skip to the section :ref:`invoking make<invokingMake>` below. Also, many common configuration options (like install location) can be set through options to the ``configure`` script. + +Type ``./configure --help`` for a complete listing. Note that the configuration option is only available with the unix ``.tar`` distributions of the source. + +.. _autogen_sh: + + +.. note:: + + If you're building Ghostscript from development source out of a repository instead of from a released source package, you should run ``./autogen.sh`` instead of ``./configure``. This script takes all the same options that ``configure`` does. + +If your system doesn't support the ``configure`` script or you don't wish to use it, you can use the traditional Ghostscript ``makefile`` system, editing the options by hand to match your system as described below. Fortunately, the only ``makefiles`` you're likely to want to change are relatively small ones containing platform-specific information. + + +.. _platformSpecificMakefiles: + +Platform-specific makefiles +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Makefile + - Used for + * - ``Makefile.in`` + - Template ``makefile`` for the ``autoconf`` build. + * - ``psi/msvc.mak`` + - MS Windows with Microsoft Visual Studio 2003 and later. + * - ``base/unix-gcc.mak`` + - Unix with ``gcc``. + * - ``base/unixansi.mak`` + - Unix with ANSI C compilers other than ``gcc``. + + +A number of platform indepdent ``makefiles`` in each of the core Ghostscript source directories. Since these files can change from one Ghostscript version to another, sometimes substantially, and since they all include documentation for the various options, here we don't duplicate most of that documentation: we recommend strongly that you review the entire ``makefile`` specific for your operating system and compiler before building Ghostscript. + + +.. _PreparingMakefiles: + +Changes for your environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Assuming you have opted not to use the ``configure`` script or the default Microsoft Visual Studio bulid, you must edit the platform-specific ``makefile`` to change any of these: + +- The name of the ``makefile`` itself (``MAKEFILE`` macro). + +- The locations to install Ghostscript files (prefix etc.). + +- The default search paths for the initialization and font files (``GS_LIB_DEFAULT`` macro). + +- The debugging options (``DEBUG`` and ``TDEBUG`` macros). + +- Which optional features to include (``FEATURE_DEVS``). + +- Which device drivers to include (``DEVICE_DEVS`` and ``DEVICE_DEVS{1--20}`` macros). + +- Default resolution parameters for some printer drivers (``devs.mak`` or ``contrib.mak``, whichever defines the driver). + + + +In general these will be set to commonly sensible values already, but may not be ideal for your specific case. + + + +The :ref:`platform-specific makefiles<platformSpecificMakefiles>` include comments describing all these except the ``DEVICE_DEVS`` options. These are described in ``devs.mak`` and ``contrib.mak``, even though the file that must be edited to select them is the :ref:`platform-specific makefile<platformSpecificMakefiles>`. + +Some platform-specific options are described in the sections for individual platforms. See the "Options" section near the beginning of the relevant ``makefile`` for more information. + + + + + +Selecting features and devices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You may build Ghostscript with any of a variety of features and with any subset of the available device drivers. The complete list of features is in a comment at the beginning of ``gs.mak``, and the complete list of drivers in comments at the beginning of ``devs.mak`` and ``contrib.mak``. To find what devices a platform-specific ``makefile`` selects to include in the executable, look in it for all lines of the form: + + +.. code-block:: bash + + FEATURE_DEVS={list of features} + DEVICE_DEVS*={list of devices} + + +For example, if the ``makefile`` has: + + +.. code-block:: bash + + FEATURE_DEVS=$(PSD)level2.dev + + +indicating that only the PostScript Level 2 facilities should be included, you might make it: + + + +.. code-block:: bash + + FEATURE_DEVS=$(PSD)level2.dev $(PSD)pdf.dev + + +to add the ability to interpret PDF files. (In fact, ``FEATURE_DEVS`` in the current Unix ``makefiles`` already includes ``$(PSD)pdf.dev``.). + +It is extremely important that ``FEATURE_DEVS`` is set correctly. Currently, the default builds will include a complete feature set, and as such most of those building Ghostscript will have no need to change it. Only those working in heavily resource constrained environment will want to experiment, and it is vital that the implications of such changes be understood, otherwise Ghostscript may behave in unexpected or apparently incorrect ways, or may even fail to build. + + +The Unix ``makefile`` also defines: + + +.. code-block:: bash + + DEVICE_DEVS=$(DD)x11.dev + + +indicating that the X Windows driver should be included, but since platform-specific ``makefiles`` as distributed normally include many of the possible features and drivers, you will probably rather remove from the ``makefile`` the features and drivers you don't want. It does no harm to include unneeded features and devices, but the resulting executable will be larger than needed. + +You may edit the ``FEATURE_DEVS`` line to select or omit any of the features listed near the beginning of ``gs.mak``, and the ``DEVICE_DEVS*`` lines to select or omit any of the device drivers listed near the beginning of ``devs.mak`` and ``contrib.mak``. ``GS_DEV_DEFAULT`` is a string containing whitespace separate device names, and give the devices Ghostscript should attempt to use (and the order) if no device is specified on the command line; see the usage documentation for how to select an output device at run time using the ``-sDEVICE=`` switch. If you can't fit all the devices on a single line, you may add lines defining: + +.. code-block:: bash + + DEVICE_DEVS1=$(DD){dev11}.dev ... $(DD){dev1n}.dev + DEVICE_DEVS2=$(DD){dev21}.dev ... $(DD){dev2n}.dev + + +etc., up to ``DEVICE_DEVS15``. Don't use continuation lines -- on some platforms they don't work. + + +.. note:: + + If you want to include a driver named ``xxx``, you must put ``$(DD)xxx.dev`` in ``DEVICE_DEVS*``. Similarly, if you want to include a feature related to the PostScript or PDF language interpreters (PostScript level 1 .. 3, or other language features such as the ability to read EPSF files or TrueType font files), you must represent it as ``$(PSD)xxx.dev``. + + +Precompiled run-time data +"""""""""""""""""""""""""""""""""" + +Ghostscript normally reads a number of external data files at run time: initialization files containing PostScript code, fonts, and other resources such as halftones. By changing options in the top-level ``makefile`` for the platform, you can cause some of these files to be compiled into the executable: this simplifies installation, improves security, may reduce memory requirements, and may be essential if you are planning on putting Ghostscript into ROM. Compiling these files into the executable also means the executable is (largely) self-contained, meaning initialization files, font files, resource files and ICC profile files are certain to be available and accessible. In general, Ghostscript should initialize more quickly, and files (especially PDF) files making heavy use of the built-in fonts will interpret more quickly. + +For those distributing Ghostscript binaries, compiling those files into the executable has another implication, any site-specific customizations (such as font and ``CIDFont`` substitutions) are slightly more complex to implement - see: :ref:`How Ghostscript finds files<Use_How Ghostscript finds files>` for how to influence where Ghostscript searches for files. Furthermore, if the files Ghostscript uses are also required to be accessible by applications other than Ghostscript (the mostly case for this would be font files and ICC profile files), having those files compiled into Ghostscript maybe suboptimal, essentially require two copies of the file data to be distributed (one set built into Ghostscript, and the other as "normal" files accessible outside of Ghostscript. + + + +Compiling the initialization files (``Resource/Init/gs_init.ps``, etc.) into the executable is the default. To disable this, change the 1 to a 0 in the line: + + +.. code-block:: postscript + + COMPILE_INITS=1 + + +Or, if you use the configure based Unix-style build, you can disable ``COMPILE_INITS`` by adding the option ``--disable-compile-inits`` to the invocation of configure + +Files are now compiled into the executable as a ``%rom%`` file system that can be searched, opened, etc. as with the normal (``%os%``) file system. The data is (mostly) compressed. Several of the initialisation files (those in ``Resource/Init``) are also converted to binary Postscript encoding, and "merged" into a single monolithic file - this is done for both size and speed optimization. Files that are often customized for individual installations (such as ``Fontmap`` and ``cidfmap``) are not merged into the single file and thus installation specific versions can be used. + +The set of files built into the ``%rom%`` file system is specified in the ``psi/psromfs.mak`` file. By default the set of files built into the rom file system comprises all the resource files Ghostscript requires to run successfully (all the files under ``Resource`` directory, and those under the ``iccprofiles`` directory). Refer to the file ``base/mkromfs.c`` for a description of the parameters that control source and destination pathnames, file enumeration exclusion, compression, etc. + +Fonts normally are compiled into the executable using ``mkromfs`` (above) from the ``Resource/Font/`` directory. + +Similarly, Halftone resources can be compiled into the executable using ``mkromfs``, but also threshold-array halftones can be compiled into the executable. See the "Compiled halftone" section of ``int.mak`` for a sample ``makefile`` fragment, ``genht.c`` for the syntax of halftone data files, and ``lib/ht_ccsto.ps`` for a sample data file. Note that even though the data files use PostScript syntax, compiled halftones do not require the PostScript interpreter and may be used with the graphics library alone. + + +Setting up "makefile" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After going through the steps just described to :ref:`unpack the sources<Unpack>`, configure the build and make any desired :ref:`changes to the makefiles<PreparingMakefiles>`. As the final step in preparing to build Ghostscript you must usually associate the name "makefile" with the correct ``makefile`` for your environment so the make command can find it. See the section on your particular platform for how to do that if necessary. + +On unix systems, ``./configure`` (or if checked out of git, ``./autogen.sh``) should create a ``Makefile`` which works in most scenarios. Manual tampering and editing should rarely be needed nor recommended. + + + + +.. _invokingMake: + + +Invoking "make" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``make`` + Builds Ghostscript without debugging options. + + +.. _Make_Debugging: + +``make debug`` + Builds Ghostscript with debugging options and additional internal error checks. The program will be somewhat larger and slower, but it will behave no differently unless you actually turn on debugging options at execution time with the ``-DDEBUG`` or :ref:`-Z command line switches<Use_Debugging>` described in the usage documentation. + +``make pg`` + On Unix platforms, builds with the ``-pg`` compiler switch, creating an executable for time profiling. + +``make install`` + After building, installs the Ghostscript executables, support files, and documentation, but does not install fonts. See the :ref:`installation documentation<Install.htm>`. + +``make (debug)clean`` + Deletes all the files created by the build process (relocatables, executables, and miscellaneous temporary files). If you've built an executable and want to save it, move it first to another place, because "make clean" deletes it. + + +.. _Make_SharedObject: + +``make so`` + On some platforms (Linux, \*BSD, Darwin/Mac OS X, SunOS), it is possible to build Ghostscript as a shared object library. There is a corresponding ``make soclean`` for cleaning up. + +``make sanitize`` + Builds Ghostscript with ``AddressSanitizer``. Output is placed in ``./sanbin``. + + + +.. note:: + + - On most platforms some of these simple instructions don't quite work in one way or another. Read the section on your specific platform. + + - If you are attempting to build a statically linked executable, you will probably need to add libraries to the linker options (libraries that are normally pulled-in automatically by the dynamic linker). These can be added at the make command line using the ``EXTRALIBS=`` option. Unfortunately, the set of libraries that may be required varies greatly depending on platform and configuration, so it is not practical to offer a list here. + + + +Cross-compiling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Cross-compiling is not fully supported by the configure script (such support is a work-in-progress). + +You can either use ``base/unixansi.mak`` or ``unix-gcc.mak`` as the basis for a cross-compile ``makefile``, or use configure to create a basic ``Makefile`` as the basis. And modify to suit. + +You can set the compiler to your cross-compiler for configure by doing: + + +.. code-block:: bash + + ./configure CC=<cross-compiler executable> + + +and configure will then run its checks (as best it can) with the cross-compiler. + +If you do so, you should also give configure the option to set the target architecture endianness: ``--enable-big-endian`` or ``--enable-little-endian``. + +It would also be wise to review the settings shown in the output of ``./configure --help`` for any that would be applicable to your target. + + +The Ghostscript build system uses several interim executables, built and run on the host, as such, even when cross-compiling, a host native compiler is also required. You must edit your ``makefile`` to ensure that is available. Find the line that starts: + +``CCAUX=`` + +and set that to your host compiler. + +If you did not use configure or did not set the CC variable for configure, you must also set the: + +``CC=`` + +to your cross-compiler. + +The Ghostscript build system uses a utility called ``genarch`` (see ``base/genarch.c`` for details) to interrogate the environment and generate a header file describing the architecture for which Ghostscript is being built. As this is run on the ``host`` it will generate header for the ``host architecture`` rather than that of the target. + +For cross compiling, you must create (or modify) a header file (``arch.h``) which accurately describes the ``target architecture``. Then you must edit your ``makefile`` by finding the line: + +``TARGET_ARCH_FILE=`` + +and set it to the path to, and file name of your custom ``arch.h`` file. With that setting, ``genarch`` will still be run, but rather than interrogate the current environment, it will copy the contents of your custom ``arch.h`` to the build. + + + + +How to build Ghostscript from source (PC version) +------------------------------------------------------------- + +All Ghostscript builds in PC (DOS and MS Windows) environments are 32- or 64-bit: 16-bit builds are not supported. The relevant ``makefiles`` are: + + +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - Makefile + - Construction tools + - For environment + * - ``msvc.mak`` + - :ref:`Microsoft Visual Studio .NET 2003 (or later)<Microsoft build>` + - MS Windows 32/64-bit + * - ``Makefile.in`` + - :ref:`Cygwin/gcc<Cygwin build>` + - Cygwin (Use Unix configure) + + +Ghostscript requires at least MS Windows 95 (although we no longer actively test nor support Win95, we have not deliberately done anything to break compatibility with it). We recommend at least MS Windows NT 4.0. + +For building, Ghostscript requires at least Visual Studio .NET 2003, and we recommend at least Visual Studio 2005 (required for 64 bit Windows support). + + +.. note:: + + The ``make`` program supplied with Visual Studio (and earlier Visual C++ versions) is actually called ``nmake``. We refer to this program generically as make everywhere else in this document. + +You must have ``cmd.exe`` in your path to build Ghostscript (using the Visual Studio command prompt is ideal). After making any changes required to choose features and devices to build into the executable, you can then invoke ``make`` to build the executable. + + +.. _Microsoft build: +.. _Make Building with Visual Studio: + +Microsoft Visual Studio +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Using Microsoft Visual Studio +"""""""""""""""""""""""""""""""" + +To build the required DLLs, load ``/windows/ghostpdl.sln`` into Visual Studio, and select the required architecture from the drop down - then right click on 'ghostpdl' in the solution explorer and choose "Build". + +Further details +"""""""""""""""""" + +The Ghostscript source distribution ships with ``project`` and ``solution`` files for Visual Studio 2005 and later. These can be found in the ``windows`` directory. The ``project(s)`` are ``nmake projects`` which means that rather than Visual Studio controlling the build directly, it delegates the build process to the ``nmake``. + +Beyond lacking support for parallel builds (``nmake`` cannot support parallel builds), there should be little visible difference between a conventional VS project and an ``nmake project`` to the user of the VS graphical interface. The only exception to that is if you have to make changes to build options beyond those available in the defined build configurations. In that case, you need to find the ``Nmake`` tab in the project ``Property Pages`` and modify the appropriate entry: ``Build Command Line``, ``Rebuild All Command Line`` and/or ``Clean Command Line``. + +As mentioned above, ``nmake`` does not support parallel builds. If you have downloaded and are building the GhostPDL source archive (which contains Ghostscript, GhostPCL, GhostXPS, and GhostPDL "products"), the ``GhostPDL.sln`` contains individual projects for each product but, as a result of the limitations of ``nmake`` the products cannot be built in parallel, because ``nmake's`` lack of parallel build awareness means it cannot manage the dependencies shared between the products, and may fail as multiple builds attempt to access the same dependencies. + +To build all the products in one action, use the ``All`` "pseudo-project". The ``All`` project uses a single nmake invocation to build all the supported products. + + +.. note:: + + Changing the ``Output`` property in the ``Nmake`` properties will not change the name of the executable - to do that requires editing of the ``psi/msvc.mak makefile``, or you can add: ``GS=myname.exe`` to the ``nmake`` command line. + + +Using the command line +"""""""""""""""""""""""""""""""" + +Ghostscript can be made using the Windows command prompt or one of the various command line shells made for Windows, as long as the command line syntax is compatible with the Windows ``CMD.exe``. The Visual Studio command prompt is ideal. + +In order for the ``makefiles`` to work properly, two items may have to be changed. An attempt is made to select the correct version of Microsoft Visual C++ based on the version of ``nmake``. If this doesn't work it will default to version 6.x. If the auto-detection does not work, and you are not using version 6.x then before building, in ``psi\msvc.mak`` find the line ``#MSVC_VERSION=6`` and change it to ``MSVC_VERSION=4``, ``MSVC_VERSION=5``, ``MSVC_VERSION=7`` or ``MSVC_VERSION=8`` and so on. + +In some cases the location of the Microsoft Developer Studio, needs to be changed. The location of Microsoft Developer Studio is defined by the value of ``DEVSTUDIO``. There are several different definitions of ``DEVSTUDIO`` in ``psi\msvc.mak``. There is one for each of the currently supported versions of Microsoft Visual C++ (4, 5, 6, 7, 7.1 and 8). + +The normal installation process for Microsoft Visual C++ includes setting the location of the Microsoft Visual C++ executables (``cl.exe``, ``link.exe``, ``nmake.exe``, ``rc.exe``) in your ``PATH`` definition and the ``LIB`` and ``INCLUDE`` environment variables are set to point to the Microsoft Visual C++ directories. If this is true then the value for ``DEVSTUDIO`` can be changed to empty, i.e. ``DEVSTUDIO=`` + +If ``PATH``, ``LIB``, and ``INCLUDE`` are not correctly set then the value for ``DEVSTUDIO`` needs to be defined. For example, for version 6.0, the default definition for the location for the Microsoft Developer Studio is: ``DEVSTUDIO=C:\Program Files\Microsoft Visual Studio`` If the path to Microsoft Developer Studio on your system differs from the default then change the appropriate definition of ``DEVSTUDIO``. (Remember that there is a separate definition of ``DEVSTUDIO`` for each version of ``MSVC``, so be sure to change the correct definition.) + +To run the make program, give the command: + + +.. code-block:: bash + + nmake -f psi\msvc.mak + + +Rather than changing ``psi/msvc.mak``, these values can also be specified on the make command line, i.e. + + +.. code-block:: bash + + nmake -f psi\msvc.mak MSVC_VERSION=6 DEVSTUDIO="C:\Program Files\Microsoft Visual Studio" + nmake -f psi\msvc.mak MSVC_VERSION=7 DEVSTUDIO="C:\Program Files\Microsoft Visual Studio .NET" + + +Note that double quotes have been added around the path for ``DEVSTUDIO`` due to the spaces in the path value. + +This command line can also be put into a ``batch`` file. + +You may get warning messages during compilation about various undefined and/or unsupported switches - this is because the compiler switches are set in the ``makefiles``, and are applied when building with all versions of Visual Studio, but not all options are supported (or required) by all versions of Visual Studio. These warnings are benign and can be ignored. + + + +Microsoft Environment for 64-bit +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Building Ghostscript for 64-bit Windows (AMD64 processor) requires Microsoft Visual Studio .NET 2005 or Microsoft Visual Studio 2008 or later on 64-bit Windows. Cross compiling on 32-bit Windows is possible. + +Compiling for 64-bit is similar to the Microsoft Environment instructions above, but with the addition of a ``WIN64`` define. + +To make Ghostscript use: + + +.. code-block:: bash + + nmake -f psi/msvc.mak WIN64= + + +Making self-extracting installers +"""""""""""""""""""""""""""""""""""""" + +You can build self-extracting Windows installers based on NSIS (Nullsoft Scriptable Install System). To do so, use the ``nsis makefile`` target as well as any other options, for example: + + +.. code-block:: bash + + nmake -f psi/msvc.mak WIN64= nsis + + +will create an ``nsis`` based installer for Ghostscript built for 64 bit Windows systems. + + +Microsoft Environment for WinRT +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript can be built in the form of a ``win32 DLL`` for use within a Windows Runtime application or Windows Runtime component. Building for WinRT requires use of Microsoft Visual Studio 2012. There is a solution file that can be loaded into VS 2012, in the directory ``winrt``. + +The WinRT application or component should include ``iapi.h`` from ``gs/psi`` and link with ``gsdll32metro.lib`` from ``gs/debugbin`` or ``gs/releasebin``. Also any app using Ghostscript either directly or via a component should add ``gsdll32metro.dll`` as "content". This inclusion of the dll is necessary so that it will be packaged with the app. If one wishes to be able to run the debugger on Ghostscript then ``gsdll32metro.pdb`` should also be added as content. + + +.. _Cygwin build: + +Cygwin32 gcc +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +It is possible to compile Ghostscript for MS Windows using the Cygwin32 gcc compiler, ``GNU make``, using the "configure" generated ``Makefile``. + +Information about this compiler and environment is at the `Cygwin site`_. + + +MSys/Mingw +"""""""""""""" + +The configure build can be used to build Ghostscript on ``MSys/Mingw`` systems, but with a caveat. The ``msys-dvlpr`` adds header files into the compiler's header search paths which cause a clash, and the build will fail as a result. If you have the ``msys-dvlpr`` package installed, and until a better solution is available you can work around this by temporarily renaming the ``\mingw\msys\1.0\include`` directory so those headers are no longer found by the compiler. + + + +.. _Make Building with MacOS: + +How to build Ghostscript from source (MacOS version) +--------------------------------------------------------- + +MacOS X +~~~~~~~~~~~~~ + +The unix source distribution (``.tar.gz``) builds fine on Darwin/MacOS X, albeit without a display device. You can generally just use the ``Makefile`` generated by configure as your top-level ``makefile`` and get a reasonable default build. This will allow you to use Ghostscript from the command line as a BSD-layer tool to rasterize postscript and pdf to image files, and convert between the high-level formats supported by Ghostscript. See the :ref:`instructions for the unix build<MakeHowToBuildForUnix>` below for details of how to customize this build. + + +.. note:: + + If you have MacPorts_ installed, it can "confuse" the configure script because it includes some librares which duplicate the "system" ones. This can cause missing symbol link errors. In order to resolve this, you can do: ``LDFLAGS="-L/usr/lib" ./configure``. That will force the linker to search the default directory first, and thus pick up the system libraries first. + +It is also possible to build "universal binaries" for MacOS X, containing i386 and x86_64 binaries in one file, using the ``Makefile`` from ``configure``. This can be achieved by using the following invocation of ``configure``: + + +.. code-block:: bash + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc" CPP="gcc -E" + + + +You can choose the combination of valid architectures (i386/x86_64/ppc) that you require. + +The separate options for ``CC`` and ``CPP`` are required because some of the features used by configure to explore the capabilities of the preprocessor are not compatible with having multiple ``-arch`` options. + +Building a shared library on MacOS X is the same as for other Unix-like systems, the "configure" step is done normally, and the "so" target is given to the make invocation, thus: + +.. code-block:: bash + + make so + +The only difference compared to other Unix-like systems is that on OS X the resulting shared library is created with the ".dylib" file name extension, instead of the more usual ".so". + + +.. _Make Building with Unix: +.. _MakeHowToBuildForUnix: + +How to build Ghostscript from source (Unix version) +--------------------------------------------------------- + +Ghostscript now ships with a build system for unix-like operating systems based on ``GNU Autoconf``. In general the following should work to configure and build Ghostscript: + + +.. code-block:: bash + + ./configure + make + +or + +.. code-block:: bash + + ./configure + make so + +for building Ghostscript as a shared library. + +Please report any problems with this method on your system as a bug. + +On modern unix systems, ``./configure`` should create a ``Makefile`` which works in most scenarios. Manual tempering and editing should rarely be needed nor recommended. + +.. note:: + + If you're building Ghostscript from development source out of a repository instead of from a released source package, you should run ``./autogen.sh`` instead of ``./configure``. This script takes all the same options that ``configure`` does. + +(deprecated; see Autoconf-based method above) For the convenience of those already familiar with Ghostscript, the old method based on hand-edited makefiles is still possible but no longer supported (and in many cases, simply do not work without substantial expert manual-editing effort). It may also be helpful in getting Ghostscript to build on very old platforms. The rest of this section deals exclusively with that older method and includes numerous pointers regarding legacy systems. + +(deprecated; see Autoconf-based method above) Before issuing the make command to build Ghostscript, you have to make some choices, for instance: + +- Which compiler to use. + +- What features and devices to include. + +- Whether to use system libraries for PNG and zlib. + +- How to handle issues for your particular platform. + +Be sure to check the sections on tool-, OS-, and hardware-specific issues for notes on your particular platform and compiler. In fact, that is the first place to check if you build Ghostscript and it crashes or produces obviously incorrect results. + + + + +make tools +~~~~~~~~~~~~~~ + +You require a make tool which supports separate directories for the derived objects (such as object files, executables and dynamically created header files) and the source files. + +In general, GNU make is the recommended choice, and some features (such as the building of the Linux/Unix shared library build ("make so") are only available with GNU make. + +Other make implementations are known to work, but are not guaranteed to do so. + + +GNU make +""""""""""""" + +Current versions of ``GNU make`` have no problems building Ghostscript. + + + +OS-specific issues +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +MacOS or Linux / OpenBSD +"""""""""""""""""""""""""""""""""""""""" + +Running the ``autogen.sh`` script from the command line depends on having both ``autoconf`` and ``automake`` installed on your system. + +If this software is not already on your system (usually this can be found in the following location: ``usr/local/bin``, but it could be located elsewhere depending on your setup) then it can be installed from your OS's package system. + +Alternatively, it can be installed from `GNU Software`_ + + +Or, it can be installed via Brew by running: + +.. code-block:: bash + + brew install autoconf automake + +Once built, these libraries can be found in your ``ghostpdl/sobin/`` or ``ghostpdl/sodebugbin`` location depending on your build command. + + + +H-P RISC workstations +"""""""""""""""""""""""""" + +(see Autoconf-based method above) + +- HP-UX versions before 11.0 do not support ``POSIX`` threads. Set ``SYNC=nosync`` in the ``makefile`` before building. + +- Ghostscript builds on H-P machines with either ``GNU gcc`` or H-P's ANSI-capable ``cc``. The minimal, non-ANSI-capable ``cc`` that shiped with some basic HPUX system does not work. If ``cc`` on your system doesn't accept the ``-Aa`` switch, then you need to get the full ``cc`` or ``gcc``. + +- If you use H-P's compiler, be sure you have upgraded to a recent release. Many bizarre symptoms have been reported trying to build Ghostscript with older, buggier compilers, for example: + + - The link step fails with a message about "max" not being defined. + + - The build succeeds, but the resulting executable fails to start up, with an error message like "Initializing... Unrecoverable error: typecheck in .registerencoding". + + - The build succeeds, but the resulting executable produces a black background on the first page of output. + +- It is reported that On HPUX 9.* you need at least compiler patch PHSS_5723 and ``dld.sl`` patch PHSS_5734 to build Ghostscript. (As of late 1997, those patches are long obsolete; the current patches are compiler PHSS_10357 and ``dld.sl`` PHSS_11246. It is unknown whether current Ghostscript releases work with ``compiler/dld.sl`` versions older than these). + +- On HPUX 10.*, we don't know what combinations of compiler version and switches work. It is reported that On HPUX 10.20, setting ``CC=c89`` and ``CFLAGS=+O3 $(XCFLAGS)`` works, contradicting the information in the next paragraph, but this may be dependent on the specific compiler version. + +- In either HPUX version, you need to set ``CC=cc -Aa`` (or use ``-Ae`` if you prefer), and set ``CFLAGS=-D_HPUX_SOURCE -O $(XCFLAGS)``. Higher levels of optimization than -O may work depending on your compiler revision; some users have reported success with +O3, some have not. + +- Some users have reported needing ``-DNOSYSTIME`` and ``-D_POSIX_SOURCE`` in ``CFLAGS``, but recent tests do not show these to be necessary. + +- If you use ``gcc``, it's a good idea to have a recent release -- at the very least 2.7.2.1 or later. You may be able to get a working executable with an older ``gcc`` by removing ``-O`` from ``CFLAGS``. + + +IBM AIX +"""""""""""""""""""""""""" + +We recommend installing ``gcc`` and ``GNU make``, and using the Autoconf-based method. + +Other combinations are known to work, but are less well supported. + +Recent veresions of Ghostscript can trigger a 'TOC overflow' error with some compilers on AIX. If this occurs, use the linker flag ``-bbigtoc``, which can either be added to your configure options: + + +.. code-block:: bash + + configure LDFLAGS="-Wl,-bbigtoc" + + +Or on the make command line: + + +.. code-block:: bash + + make XLDFLAGS="-Wl,-bbigtoc" + + + +Silicon Graphics +"""""""""""""""""""""""""" + +(see Autoconf-based method above) + +Users have had a lot of problems with the MIPSpro compilers on SGI systems. We recommend using ``gcc``. If you do choose to use the MIPSpro compiler, please read the following carefully. + +- To make the optimizer allocate enough table space, set: + + ``CFLAGS="-Olimit 2500"`` (for older compilers) + ``CFLAGS="-OPT:Olimit=2500"`` (for newer compilers) + +- MIPSpro compiler version 3.19 is "older", and 7.1 is "newer"; we aren't sure at what point in between the latter syntax was introduced. + +- With the compiler shipped with Irix 5.2, use the ``-ansi`` option. + +- The SGI C compiler may produce warnings about "Undefined the ANSI standard library defined macro stdin/stdout/stderr". To suppress these warnings, add ``-woff 608`` to the definition of ``CFLAGS``. + +- The SGI C compiler shipped with Irix 6.1 and 6.2 will not compile ``zlib/deflate.c`` properly with optimization. Compile this file separately without ``-O``. + +- With IRIX 6.5.x and the MIPSpro 7.x compilers there have been reports about incorrect output and binaries that cause segmentation faults. Various solutions have been suggested and you may want to try them in this order, until you get a working binary: + + - Compile ``idict.c`` and ``isave.c`` separately without optimization after doing a normal compile; then relink.e.g.: + + .. code-block:: bash + + cc -OPT:Olimit=2500 -I. -I./obj -o ./obj/idict.o -c ./idict.c + cc -OPT:Olimit=2500 -I. -I./obj -o ./obj/isave.o -c ./isave.c + + + - Set ``CFLAGS=`` (no optimization). + + - Use only ``-O2``. Compiler produces incorrect output with ``-O3`` or ``-Ofast=ip32 -show``. + + - Irix 6.5.1m with MIPSpro compiler 7.2.1.1m, Irix 6.5.3m with MIPSpro compiler 7.2.1, and probably other 6.5x / 7.2x combinations require compiling with the ``-o32`` option. Compiling with the (default) ``-n32`` option produces non-working executables. ``-O2`` is OK (possibly except for ``idict.c``), but not ``-O3``. + + +Oracle/Sun +~~~~~~~~~~~~~~~~ +(see Autoconf-based method above) + +- The Sun unbundled C compiler (SC1.0) doesn't compile Ghostscript properly with the ``-fast`` option: Ghostscript core-dumps in ``build_gs_font``. With that compiler use ``-g``, or use ``gcc`` instead. + +- The Sun version of ``dbx`` often gives up with an error message when trying to load Ghostscript. If this happens, use ``GNU gdb`` instead. (``gdb`` is more reliable than ``dbx`` in other ways as well). + +- A bug in some versions of ``zlib`` results in an undefined symbol ``zmemcmp`` when compiling with Sun ``cc``. Use ``gcc`` instead. + + + +Solaris +~~~~~~~~~~~~~~~~ + +- Solaris 2.2 may require setting ``EXTRALIBS=-lsocket``. Solaris 2.3 and later seem to require ``EXTRALIBS=-lnsl -lsocket -lposix4``. + +- For Solaris 2.6 (and possibly some other versions), if you set ``SHARE_LIBPNG=1``, ``SHARE_ZLIB=1``, or ``SHARE_JPEG=1``, you may need to set ``XLDFLAGS=-R /usr/local/xxx/lib:/usr/local/lib`` using the full path names of the relevant directories. + +- Solaris 2.n uses ``/usr/openwin/share/include`` for the X11 libraries rather than ``/usr/local/X/include``. + +- Solaris 2.n typically has Type 1 fonts in ``/usr/openwin/lib/X11/fonts/Type1/outline``. + +- For Solaris 2.n in the ``makefile`` you must change the definition of ``INSTALL`` from ``install -c`` to ``/usr/ucb/install -c``. + +- You may need to set ``XLIBDIR`` to the directory that holds the X11 libraries, as for other SVR4 systems. Set ``-DSVR4`` in ``CFLAGS``. + +- If you are using the SunPRO C compiler, don't use optimization level ``-xO3``. On ``SPARC`` platforms the compiler hangs; on Intel platforms the generated code is incorrect. With this compiler on Intel, do not use the ``-native`` flag: floating point computations become unacceptably inaccurate. You can use ``-xcg92`` (``SPARC V8``) and ``-dalign`` for better performance. + +- One user reported compiling from source on a Linux NFS mounted volume failed. Compiling from a local volume was the workaround. + + +Other environments +-------------------- + +Environments lacking multi-threading +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All environments mentioned here by name have multi-threading capability. However, if your environment doesn't, you can remove all need for multi-threading by setting ``SYNC=nosync`` in the top-level ``makefile``. Note that you will not be able to use any so-called "async" drivers (drivers that overlap interpretation and rasterization) if you do this. No such drivers are in the ``DEVICE_DEVS*`` lists of any ``makefile`` that we distribute. + +Plan 9 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use ``unix-gcc.mak``, editing it to define: + +.. code-block:: bash + + CC=cc GCFLAGS=-D_BSD_EXTENSION -DPlan9 + +You will also probably have to edit many path names. + + + +.. _Make_USFTBuild: + + +How to build Ghostscript with UFST +------------------------------------------- + + +.. note:: + + This section is only for customers who have a Monotype Imaging UFST license. Other users please skip this section. + + +Ghostscript sources do not include UFST sources. You need to obtain them separately. The Ghostscript distributed source include only some source modules that provide a bridge to UFST. You will also need an additional, UFST specific makefile: contact Ghostscript support for more information. + +If optioned in, the Ghostscript build system will build the UFST as part of the normal bulid process (previously, the UFST was required to be built separately). + +To build Ghostscript with UFST, specify additional options for "make": + +``UFST_BRIDGE=1`` + Forces the UFST bridge to build. + +``UFST_ROOT=path`` + Specifies the path to UFST root directory or folder. + +``UFST_CFLAGS=options`` + Specifies C compiler options for UFST library. Refer to UFST manual for information about them. + +``UFST_LIB_EXT=extension`` + Sets the file name extension for object libraries. You must use the appropriate one for your platform and linker. + + +An example for Unix/GCC : + + +.. code-block:: bash + + UFST_BRIDGE=1 UFST_ROOT=../ufst UFST_CFLAGS=-DGCCx86 UFST_LIB_EXT=.a + + +Starting with Ghostscript 9.x (Summer 2010), the above options are conveniently inserted in the ``Makefile`` with (this also automatically disable the freetype bridge): + +.. code-block:: bash + + ./configure --with-ufst=../ufst + +For Windows/MSVC you need only specify ``UFST_ROOT``. ``msvc.mak`` sets the other options automatically. + + + + + + + + + +.. External links: + + +.. _git: http://git-scm.com/ +.. _ghostpdl.git: http://git.ghostscript.com/?p=ghostpdl.git;a=summary + +.. _WinZip: http://www.winzip.com/ +.. _7-zip: http://www.7-zip.org/ +.. _Info-ZIP: http://www.info-zip.org/ + +.. _Ghostscript Bugzilla: http://bugs.ghostscript.com +.. _Cygwin site: http://www.cygwin.com/ +.. _MacPorts: http://www.macports.org/ + +.. _GNU Software: https://www.gnu.org/software/ + + +.. include:: footer.rst + + diff --git a/doc/src/News.rst b/doc/src/News.rst new file mode 100644 index 00000000..0395db28 --- /dev/null +++ b/doc/src/News.rst @@ -0,0 +1,17 @@ +.. title:: News + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _News.htm: + +News +============================================ + +.. raw:: html + :file: ../News.htm + + + diff --git a/doc/src/Ps-style.rst b/doc/src/Ps-style.rst new file mode 100644 index 00000000..3ad6fe9b --- /dev/null +++ b/doc/src/Ps-style.rst @@ -0,0 +1,330 @@ +.. title:: Ghostscript PostScript Coding Guidelines + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Ps-style.htm: + + +Ghostscript PostScript Coding Guidelines +============================================ + + + +Summary of the coding guidelines +----------------------------------- + +- Don't store into literals. + +- Use ``loop`` to create a block with multiple exits. + +- Use a dictionary or an array for multi-way switches. + +- Start every file with a copyright notice, the file name, and a one-line summary. + +- Comment every procedure with the arguments and result, and with the function of the procedure unless it's obvious. + +- Comment the stack contents ad lib, and particularly at the beginning of every loop body. + +- Indent every 2 spaces. + +- Always put { at the end of a line, and } at the beginning of a line, unless the contents are very short. + +- Always put spaces between adjacent tokens. + +- Use only lower-case letters and digits for names, or :ref:`Vienna style names<Naming>`, except for an initial "." for names only used within a single file. + +- Don't allocate objects in heavily used code. + +- Consider factoring out code into a procedure if it is used more than once. + + +The many rules that Ghostscript's code follows almost everywhere are meant to produce code that is easy to read. It's important to observe them as much as possible in order to maintain a consistent style, but if you find a rule getting in your way or producing ugly-looking results once in a while, it's OK to break it. + + + +Use of PostScript language features +---------------------------------------- + +Restrictions +~~~~~~~~~~~~~~~~~ + +If you need to store a value temporarily, don't write into a literal in the code, as in this fragment to show a character given the character code: + + +.. code-block:: postscript + + ( ) dup 0 4 -1 roll put show + +Instead, allocate storage for it: + + +.. code-block:: postscript + + 1 string dup 0 4 -1 roll put show + + +Protection +~~~~~~~~~~~~~~~~~ + +If an object is never supposed to change, use ``readonly`` to make it read-only. This applies especially to permanently allocated objects such as constant strings or dictionaries. + +During initialization, and occasionally afterwards, it may be necessary to store into a read-only dictionary, or to store a pointer to a dictionary in local VM into a dictionary in global VM. The operators ``.forceput`` and ``.forceundef`` are available for this purpose. To make these operators inaccessible to ordinary programs, they are removed from ``systemdict`` at the end of initialization: system code that uses them should always use ``bind`` and ``odef`` (or ``executeonly``) to make uses of them inaccessible as well. + + +Standard constructions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Multi-way conditionals +""""""""""""""""""""""""""" + +If you write a block of code with more than about 3 exit points, the usual way to do it would be like this: + + +.. code-block:: postscript + + { + ... { + ...1 + } { + ... { + ...2 + } { + ... { + ...3 + } { + ...4 + } ifelse + } ifelse + } ifelse + } + + +However, this causes the 4 logically somewhat parallel code blocks to be indented differently, and as the indentation increases, it becomes harder to see the structure visually. As an alternative, you can do it this way: + +.. code-block:: postscript + + { % The loop doesn't actually loop: it just provides a common exit. + ... { + ...1 + exit + } if + ... { + ...2 + exit + } if + ... { + ...3 + exit + } if + ...4 + exit + } loop + + +Don't forget the final exit, to prevent the loop from actually looping. + + + +Switches +""""""""""""""""""""""""""" + +Use a dictionary or an array of procedures to implement a 'switch', rather than a series of conditionals, if there are more than about 3 cases. For example, rather than: + + +.. code-block:: postscript + + dup /a eq { + pop ...a + } { + dup /b eq { + pop ...b + } { + dup /c eq { + pop ...c + } { + ...x + } ifelse + } ifelse + } ifelse + +(or using the loop/exit construct suggested above), consider: + +.. code-block:: postscript + + /xyzdict mark + /a {...a} bind + /b {...b} bind + /c {...c} bind + .dicttomark readonly def + ... + //xyzdict 1 index .knownget { + exch pop exec + } { + ...x + } ifelse + + +File structuring +~~~~~~~~~~~~~~~~~~~ + +Every code file should start with comments containing + +1. A copyright notice. + +2. The name of the file in the form of an RCS Id: + +.. code-block:: postscript + + % $Id: filename.ps $ + +3. A very brief summary (preferably only one line) of what the file contains. + +If you create a file by copying the beginning of another file, be sure to update the copyright year and change the file name. + + + +Commenting +------------ + + + +If a file has well-defined functional sections, put a comment at the beginning of each section to describe its purpose or function. + +Put a comment before every procedure to describe what the procedure does, unless it's obvious or the procedure's function is defined by the PLRM. In case of doubt, don't assume it's obvious. If the procedure may execute a deliberate 'stop' or 'exit' not enclosed in 'stopped' or a loop respectively, that should be mentioned. However, information about the arguments and results should go in the argument and result comment (described just below) if possible, not the functional comment. + +Put a comment on every procedure to describe the arguments and results: + +.. code-block:: postscript + + /hypot { % <num1> <num2> hypot <real> + dup mul exch dup mul add sqrt + } def + +There is another commenting style that some people prefer to the above: + +.. code-block:: postscript + + /hypot { % num1 num2 --> realnum + dup mul exch dup mul add sqrt + } def + + +We have adopted the first style for consistency with Adobe's documentation, but we recognize that there are technical arguments for and against both styles, and might consider switching some time in the future. If you have strong feelings either way, please make your opinion known to us. + +Put comments describing the stack contents wherever you think they will be helpful; put such a comment at the beginning of every loop body unless you have a good reason not to. + +When you change a piece of code, do *not* include a comment with your name or initials. Also, do *not* retain the old code in a comment, unless you consider it essential to explain something about the new code; in that case, retain as little as possible. (CVS logs do both of these things better than manual editing.) However, if you make major changes in a procedure or a file, you may put your initials, the date, and a brief comment at the head of the procedure or file respectively. + + +Formatting +------------- + +Indentation +~~~~~~~~~~~~~~~~~ + +Indent 2 spaces per indentation level. You may use tabs at the left margin for indentation, with 1 tab = 8 spaces, but you should not use tabs anywhere else, except to place comments. + +Indent { } constructs like this: + +.. code-block:: postscript + + ... { + ... + } { + ... + } ... + + +If the body of a conditional or loop is no more than about 20 characters, you can put the entire construct on a single line if you want: + +.. code-block:: postscript + + ... { ... } if + +rather than: + + +.. code-block:: postscript + + ... { + ... + } if + + +There is another indentation style that many people prefer to the above: + +.. code-block:: postscript + + ... + { ... + } + { ... + } ... + +We have adopted the first style for consistency with our C code, but we recognize that there are technical arguments for and against both styles, and might consider switching some time in the future. If you have strong feelings either way, please make your opinion known to us. + + + +Spaces +~~~~~~~~~~~~~~~ + +Always put spaces between two adjacent tokens, even if this isn't strictly required. E.g., + +.. code-block:: postscript + + /Halftone /Category findresource + +not: + + +.. code-block:: postscript + + /Halftone/Category findresource + + + +Naming +-------- + +All names should consist only of letters and digits, possibly with an initial ".", except for names drawn from the PostScript or PDF reference manual, which must be capitalized as in the manual. In general, an initial "." should be used for those and only those names that are not defined in a private dictionary but that are meant to be used only in the file where they are defined. + +For edits to existing code, names made up of multiple words should not use any punctuation, or capitalization, to separate the words, again except for names that must match a specification. For new code, you may use this convention, or you may use the "Vienna" convention of capitalizing the first letter of words, e.g., ``readSubrs`` rather than ``readsubrs``. If you use the Vienna convention, function names should start with an upper case letter, variable names with a lower case letter. Using the first letter of a variable name to indicate the variable's type is optional, but if you do it, you should follow existing codified usage. + + + +Miscellany +-------------- + +Some useful non-standard operators +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``<obj1> <obj2> ... <objn> <n> .execn ...`` + This executes ``obj1`` through ``objn`` in that order, essentially equivalent to: ``<obj1> <obj2> ... <objn> <n> array astore {exec} forall`` except that it doesn't actually create the array. + +``<dict> <key> .knownget <value> true``, ``<dict> <key> .knownget false`` + This combines known and get in the obvious way. + +``<name> <proc> odef -`` + This defines name as a "pseudo-operator". The value of name will be executable, will have type ``operatortype``, and will be executed if it appears directly in the body of a procedure (like an operator, unlike a procedure), but what will actually be executed will be ``proc``. In addition, if the execution of ``proc`` is ended prematurely (by ``stop``, including the ``stop`` that is normally executed when an error occurs, or ``exit``) and the operand and dictionary stacks are at least as deep as they were when the "operator" was invoked, the stacks will be cut back to their original depths before the error is processed. Thus, if pseudo-operator procedures are careful not to remove any of their operands until they reach a point in execution beyond which they cannot possibly cause an error, they will behave just like operators in that the stacks will appear to be unchanged if an error occurs. + +Some useful procedures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``<object> <errorname> signalerror -`` + Signal an error with the given name and the given "current object". This does exactly what the interpreter does when an error occurs. + + +Other +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you can avoid it, don't allocate objects (strings, arrays, dictionaries, gstates, etc.) in commonly used operators or procedures: these will need to be garbage collected later, slowing down execution. Instead, keep values on the stack, if you can. The ``.execn`` operator discussed above may be helpful in doing this. + +If you find yourself writing the same stretch of code (more than about half a dozen tokens) more than once, ask yourself whether it performs a function that could be made into a procedure. + + + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/Ps2epsi.rst b/doc/src/Ps2epsi.rst new file mode 100644 index 00000000..053674f1 --- /dev/null +++ b/doc/src/Ps2epsi.rst @@ -0,0 +1,93 @@ +.. title:: Convert PostScript to Encapsulated PostScript Interchange Format + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Ps2epsi.htm: + + +Convert PostScript to Encapsulated PostScript Interchange Format +====================================================================== + + + + +The information in this document was contributed by `George Cameron`_; please direct any questions about it to him. Because the software described here is no longer being maintained, this document may be obsolete, or inconsistent with ``ps2epsi.1``. + +For other information, see the :ref:`Ghostscript overview<Ghostscript Introduction>`. + + + +Overview +----------- + +``ps2epsi`` is a utility based on Ghostscript, which takes as input a PostScript file and generates as output a new file which conforms to Adobe's Encapsulated PostScript Interchange (EPSI) format, a special form of Encapsulated PostScript (EPS) which adds to the beginning of the file, as PostScript comments, a low-resolution monochrome bitmap image of the final displayed page. Programs which understand EPSI can use this bitmap as a preview on screen of the full PostScript page. The displayed quality is often not very good, but the final printed version uses the "real" PostScript, and thus has the normal full PostScript quality. Framemaker can use EPSI. + +The `Adobe Framemaker`_ DTP system is one application which understands EPSI files, and ``ps2epsi`` has been tested using Framemaker 3.0 on a Sun workstation with a number of PostScript diagrams from a variety of sources. Framemaker on other platforms may also be able to use files made with ``ps2epsi``, although this has not been tested. + + +Usage +------- + +MS-DOS +~~~~~~~~~~ + +Using the supplied batch file ``ps2epsi.bat``, the command is: + +.. code-block:: bash + + ps2epsi infile.ps outfile.epi + + +where ``infile.ps`` is the original PostScript file, and ``outfile.epi`` is the output EPSI file to be created. + + +Unix +~~~~~~~~ + +Using the supplied shell script ``ps2epsi``, the command is: + +.. code-block:: bash + + ps2epsi infile.ps [outfile.epsi] + +where ``infile.ps`` is the input file and ``outfile.epsi`` is the output EPSI file to be created. If the output filename is omitted, ``ps2epsi`` generates one from the input filename; and any standard extension (``.ps``, ``.cps``, ``.eps`` or ``.epsf``) of the input file is replaced in the output file with the extension ``.epsi``. + + +Limitations +------------------ + +Not all PostScript files can be encapsulated, because there are restrictions in what is permitted in a PostScript file for it to be properly encapsulated. ``ps2epsi`` does a little extra work to try to help encapsulation, and it automatically calculates the bounding box required for all encapsulated PostScript files, so most of the time it does a pretty good job. There are certain to be cases, however, when encapsulation fails because of the nature of the original PostScript file. + + +Files +-------- + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - File + - Contents + * - ``ps2epsi.bat`` + - MS-DOS batch file + * - ``ps2epsi`` + - Unix shell script + * - ``ps2epsi.ps`` + - Ghostscript program which does the work + + + + + + + + +.. External links + +.. _Adobe Framemaker: http://www.adobe.com/products/framemaker/main.html +.. _George Cameron: george@bio-medical-physics.aberdeen.ac.uk + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/Psfiles.rst b/doc/src/Psfiles.rst new file mode 100644 index 00000000..c81e20f5 --- /dev/null +++ b/doc/src/Psfiles.rst @@ -0,0 +1,460 @@ +.. title:: PostScript Files Distributed with Ghostscript + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Psfiles.htm: + + +PostScript Files Distributed with Ghostscript +================================================ + + + + +Generally used system files +-------------------------------- + +``gs_*_e.ps`` +~~~~~~~~~~~~~~~~~~~~~ + These files define the Encodings known to Ghostscript. All of them except ``gs_std_e.ps`` and ``gs_il1_e.ps`` are loaded only if referred to. However some are additionally built into ``gscencs.c``. + +PostScript Encodings +"""""""""""""""""""""""" + +These files are found in the ``lib`` subdirectory of the Ghostscript source distribution. + + ``gs_ce_e.ps`` + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + + ``gs_il1_e.ps``, ``gs_std_e.ps``, ``gs_sym_e.ps`` + +PDF Encodings +"""""""""""""""""""""""" + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + + ``gs_mex_e.ps``, ``gs_mro_e.ps``, ``gs_pdf_e.ps``, ``gs_wan_e.ps`` + +Non-standard Encodings +"""""""""""""""""""""""" + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + + ``gs_dbt_e.ps`` + +These files are found in the ``lib`` subdirectory of the Ghostscript source distribution. + + ``gs_il2_e.ps``, ``gs_ksb_e.ps``, ``gs_lgo_e.ps``, ``gs_lgx_e.ps``, ``gs_wl1_e.ps``, ``gs_wl2_e.ps``, ``gs_wl5_e.ps`` + + +Pseudo-encodings +"""""""""""""""""""""""" + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + ``gs_mgl_e.ps`` + +These files are found in the ``lib`` subdirectory of the Ghostscript source distribution. + + ``gs_lgo_e.ps``, ``gs_lgx_e.ps`` + + +Other files +~~~~~~~~~~~~~~~~~~~~~ + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + +``gs_btokn.ps`` + ``gs_init.ps`` reads this in if the btoken feature is included in the configuration. It provides support for binary tokens. + +``gs_cff.ps`` + Load CFF (compressed) fonts. + +``gs_fntem.ps`` + Code for emulating PostScript fonts with non-PostScript font technologies. + +``gs_cidtt.ps`` + Code for emulating ``CID`` fonts with TrueType fonts. + +``gs_cidcm.ps`` + Code for recognizing font names of the form ``CIDFont-CMap`` (or ``CIDFont--CMap``) and creating the font automatically. + +``gs_ciddc.ps`` + Defines Decoding and ``CIDDecoding`` resource categories and related procsets. Used for for emulating PostScript fonts with non-PostScript font technologies. + +``gs_cidfm.ps`` + Provides resource mapping for ``CIDFont`` category. + +``gs_cidfn.ps`` + ``ProcSet`` for implementing ``CIDFont`` and ``CIDMap`` resources. + +``gs_cmap.ps`` + ``ProcSet`` for implementing ``CMap`` resources. + +``gs_cspace.ps`` + PostScript portion of the basic color space handling; see the extensive comment at the head of the file for information. + +``gs_dscp.ps`` + Code to compensate for badly written PostScript files by setting ``Orientation`` according to the DSC comments. + +``gs_epsf.ps`` + Allow the interpreter to recognize DOS EPSF file headers, and skip to the PostScript section of the file. + +``gs_fapi.ps`` + :ref:`Font API<Fonts FAPI>` support. + +``gs_fonts.ps`` + ``gs_init.ps`` reads this in. It initializes Ghostscript's font machinery and provides some utility procedures that work with fonts. + +``gs_frsd.ps`` + Support for the PostScript LanguageLevel 3 ``ReusableStreamDecode`` filter. + +``gs_img.ps`` + Implementation of the traditional (non-dictionary) form of the image and imagemask operators, and the colorimage operator (including the Next alphaimage facility). + +``gs_init.ps`` + Ghostscript reads this automatically when it starts up. It contains definitions of many standard procedures and initialization for a wide variety of things. + +``gs_lev2.ps`` + ``gs_init.ps`` reads this in if the Ghostscript interpreter includes Level 2 PostScript functions. It contains definitions of procedures and miscellaneous initialization for the Level 2 functions. + +``gs_ll3.ps`` + Initialize PostScript LanguageLevel 3 functions. + +``gs_resmp.ps`` + A ``procset`` for redefining resource categories with a resource map. + +``gs_res.ps`` + ``gs_init.ps`` reads this in if the Level 2 resource machinery is included. Currently, this is the case for all Level 2 configurations. + +``gs_setpd.ps`` + Implementation of the ``setpagedevice`` operator. + +``gs_statd.ps`` + ``gs_init.ps`` reads this in. It creates a dummy ``statusdict`` and some other environmental odds and ends for the benefit of PostScript files that really want to be printed on a LaserWriter. + +``gs_trap.ps`` + Stub support for the PostScript LanguageLevel 3 "In-RIP trapping" feature. + +``gs_ttf.ps`` + Support code for direct use of TrueType fonts. + +``gs_typ32.ps`` + Initialization file for Type 32 fonts. + +``gs_typ42.ps`` + Support code for Type 42 fonts (TrueType font in a PostScript "wrapper"). + +``gs_type1.ps`` + ``gs_init.ps`` reads this in if the Ghostscript interpreter includes Type 1 font capability (which it normally does). + + + + +Configuration files +------------------------ + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. Users are allowed to modify them to configure Ghostscript. + +``Fontmap`` + Font mapping table. + +``cidfmap`` + CID font mapping table. Allows substitution of a CID font for another CID font or a TrueType font for a CID font. + +``FAPIconfig`` + A configuration file for Font API client. + +``FAPIfontmap`` + Font mapping table for Font-API-handled fonts. + +``FAPIcidfmap`` + Font mapping table for Font-API-handled CID fonts. + + + +More obscure system files +------------------------------------------------ + +Unless otherwise stated, these files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + +``gs_agl.ps`` + Contains the mapping from Adobe glyph names to Unicode values, used to support TrueType fonts and disk-based Type 1 fonts. + +``gs_cet.ps`` + Sets a number of alternate defaults to make Ghostscript behave more like Adobe CPSI. Useful for running the CET conformance test suite. + +``gs_diskn.ps`` + This file implements the ``%disk IODevice`` (``diskn.dev`` feature). See the :ref:`language documentation<Language.htm>` for information on the use of the ``%disk#`` devices. These PostScript modifications primarily perform the searching of all ``Searchable`` file systems in a defined ``SearchOrder`` when a file reference does not contain an explicit ``%device%`` specifier (such as ``%os%`` or ``%disk0%``). This is required to emulate undocumented behaviour of Adobe PostScript printers that have a disk and was experimentally determined. + +``gs_kanji.ps`` + This file provides support for the Wadalab free Kanji font. It is not included automatically in any configuration. This file is stored in the ``lib`` subdirectory. + +``gs_pdfwr.ps`` + This file contains some patches for providing information to the :title:`pdfwrite` driver. It is included only if the :title:`pdfwrite` driver is included. + +``ht_ccsto.ps`` + A default stochastic CMYK halftone. This file is in the public domain. This file is stored in the ``lib`` subdirectory. + +``stcolor.ps`` + Configure the (Epson) :title:`stcolor` driver. This file is stored in the ``lib`` subdirectory. + + +PDF-specific system files +------------------------------------------------ + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + +``pdf_base.ps`` + Utilities for interpreting PDF objects and streams. + +``pdf_draw.ps`` + The interpreter for drawing-related PDF operations. + +``pdf_font.ps`` + Code for handling fonts in PDF files. + +``pdf_main.ps`` + Document- and page-level control for interpreting PDF files. + +``pdf_ops.ps`` + Definitions for most of the PDF operators. + +``pdf_rbld.ps`` + Contains procedures for bebuilding damaged PDF files. + +``pdf_sec.ps`` + PDF security (encryption) code. + +``gs_icc.ps`` + Support for ICC color profiles. These are not a standard PostScript feature, but are used in the PDF interpreter, as ICC profiles may be embedded in PDF files. + + +These files are found in the lib subdirectory of the Ghostscript source distribution. These files are templates and should not be used without modification. + +``PDFX_def.ps`` + This is a sample prefix file for creating a PDF/X-3 document with the :title:`pdfwrite` device. + +``PDFA_def.ps`` + This is a sample prefix file for creating a PDF/A document with the :title:`pdfwrite` device. + + + +Display PostScript-specific system files +------------------------------------------------ + +These files are found in the ``Resource/Init`` subdirectory of the Ghostscript source distribution. + +``gs_dpnxt.ps`` + NeXT Display PostScript extensions. + +``gs_dps.ps``, ``gs_dps1.ps``, ``gs_dps2.ps`` + ``gs_init.ps`` reads these in if the dps feature is included in the configuration. They provide support for various Display PostScript and Level 2 features. + + + +Art and examples +------------------------------------------------ + +These files are found in the ``examples`` subdirectory of the Ghostscript source distribution. + +``alphabet.ps`` + Prints a sample alphabet at several different sizes. + +``annots.pdf`` + A sample file with a wide variety of PDF "annotations". + +``colorcir.ps`` + A set of nested ellipses made up of colored bars. + +``doretree.ps`` + A 3-D image produced by a modeling program. This file is in the public domain. + +``escher.ps`` + A colored version of a hexagonally symmetric Escher drawing of interlocking butterflies. Can be printed on monochrome devices, with somewhat less dramatic results. + +``golfer.eps`` + A gray-scale picture of a stylishly dressed woman swinging a golf club. + +``grayalph.ps`` + Grayscaled text test pattern. + +``ridt91.eps`` + The RIDT '91 logo. Note that since this is an EPS file, you will have to add ``-c showpage`` at the end of the command line to print it or convert it to a raster file. + +``snowflak.ps`` + A rectangular grid of intricate colored snowflakes. (May render very slowly.) + +``text_graph_image_cmyk_rgb.pdf`` + A simple PDF containing text and graphics in both RGB and CMYK spaces. + +``text_graphic_image.pdf`` + A simple PDF containing text and graphics in RGB space. + +``tiger.eps`` + A dramatic colored picture of a tiger's head. + +``transparency_example.ps`` + A simple example of transparency. + +``vasarely.ps`` + Colored rectangles and ellipses inspired by Victor Vasarely's experiments with tilting circles and squares. + +``waterfal.ps`` + Prints text in a variety of different sizes, to help evaluate the quality of text rendering. + + + +Utilities +---------------------------- + +For more information on these utility programs, see the comments at the start of each file . The ones marked (``*``) have batch files or shell scripts of the same name (like ``bdftops`` and ``bdftops.bat``) to invoke them conveniently. + +These files are found in the ``lib`` subdirectory of the Ghostscript source distribution. + +``align.ps`` + A test page for determining the proper margin and offset parameters for your printer. + +``caption.ps`` + A file for putting a caption in a box at the bottom of each page, useful for trade show demos. + +``cat.ps``` + Appends one file to another. Primarily used to overcome the 'copy' limitation of Windows command shell for ``ps2epsi``. + +``cid2code.ps`` + A utility for creating maps from CIDs to Unicode, useful when substituting a TrueType font for an Adobe font. + +``docie.ps`` + An emulation of the CIE color mapping algorithms. + +``font2pcl.ps`` + A utility to write a font as a PCL bitmap font. + +``gslp.ps`` + A utility for doing "line printing" of plain text files. + +``gsnup.ps`` + A file that you can concatenate in front of (very well-behaved) PostScript files to do N-up printing. It is deliberately simple and naive: for more generality, use ``psnup`` (which, however, requires DSC comments). + +``jispaper.ps`` + A file that makes the b0 through b6 procedures refer to JIS B paper sizes rather than ISO B. + +``landscap.ps`` + A file that you can put in front of your own files to get them rendered in landscape mode. + +``mkcidfm.ps`` + A utility for creating a CID font mapping table cidfmap from fonts found in a specified directory. + +``pdf2dsc.ps`` + A utility to read a PDF file and produce a DSC "index" file. + +``pf2afm.ps`` + A utility for producing AFM files from PFA, PFB, and optionally PFM files. + +``pfbtopfa.ps`` + A utility to convert PFB (binary) font files to PFA (text) format. + +``prfont.ps`` + A utility to print a font catalog. + +``printafm.ps`` + A utility to print an AFM file on standard output. + +``ps2ai.ps`` + A utility for converting an arbitrary PostScript file into a form compatible with Adobe Illustrator. NOTE: ``ps2ai`` doesn't work properly with Adobe's Helvetica-Oblique font, and other fonts whose original ``FontMatrix`` involves skewing or rotation. + +``ps2epsi.ps`` + A utility for converting an arbitrary PostScript file into EPSI form. + +``rollconv.ps`` + A utility for converting files produced by Macromedia's Rollup program to a Type 0 form directly usable by Ghostscript. + +``stocht.ps`` + A file that installs the ``StochasticDefault`` halftone as the default, which may improve output quality on inkjet printers. See the file for more information. + +``viewcmyk.ps`` + A utility for displaying CMYK files. + +``viewgif.ps`` + A utility for displaying GIF files. + +``viewjpeg.ps`` + A utility for displaying JPEG files. + +``viewmiff.ps`` + A utility for displaying MIFF files. + +``viewpbm.ps`` + A utility for displaying PBM/PGM/PPM files. + +``viewpcx.ps`` + A utility for displaying PCX files. + +``viewrgb.ps`` + A utility for displaying files created by ``-sDEVICE=bitrgb``. + +``viewraw.ps`` + An extended utility for displaying files created by ``-sDEVICE=bitrgb``. + + +Development tools +---------------------------- + +These files are found in the ``lib`` subdirectory of the Ghostscript source distribution. + +``acctest.ps`` + A utility that checks whether the interpreter enforces access restrictions. + +``image-qa.ps`` + A comprehensive test of the image display operators. + +``ppath.ps`` + A couple of utilities for printing out the current path, for debugging. + +``pphs.ps`` + A utility to print the Primary Hint Stream of a linearized PDF file. + +``traceimg.ps`` + Trace the data supplied to the image operator. + +``traceop.ps`` + A utility for tracing uses of any procedure or operator for debugging. + +``uninfo.ps`` + Some utilities for printing out PostScript data structures. + +``viewps2a.ps`` + A utility for displaying the output of ``ps2ascii.ps``. + +``winmaps.ps`` + A utility for creating mappings between the Adobe encodings and the Microsoft Windows character sets. + +``zeroline.ps`` + A utility for testing how interpreters handle zero-width lines. + + + +Odds and ends +---------------------------- + +These files are found in the ``lib`` subdirectory of the Ghostscript source distribution. + +``jobseparator.ps`` + Convenience file containing a job separator sequence for use when passing files with ``-dJOBSERVER``. + +``lines.`` + A test program for line joins and caps. + +``stcinfo.ps`` + Print and show parameters of the (Epson) :title:`stcolor` driver. + + + + +.. include:: footer.rst + + + diff --git a/doc/src/Readme.rst b/doc/src/Readme.rst new file mode 100644 index 00000000..85b078e6 --- /dev/null +++ b/doc/src/Readme.rst @@ -0,0 +1,239 @@ +.. title:: Ghostscript Introduction + + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Ghostscript Introduction: +.. _Readme.htm: + + +Introduction +=================================== + + +This document is a roadmap to the Ghostscript documentation. +After looking through it, if you want to install Ghostscript and not only use it, we recommend you read :ref:`How to install Ghostscript<Install.htm>`, and :ref:`How to compile Ghostscript<Make.htm>` from source code (which is necessary before installing it on Unix and VMS systems). + + +.. _WhatIsGhostscript: + +What is Ghostscript? +---------------------- + +There are various products in the Ghostscript family; this document describes what they are, and how they are related. + + + + + +Ghostscript +~~~~~~~~~~~~~~~~ + +Ghostscript is an interpreter for PostScript® and Portable Document Format (PDF) files. + +Ghostscript consists of a PostScript interpreter layer, and a graphics library. The graphics library is shared with all the other products in the Ghostscript family, so all of these technologies are sometimes referred to as Ghostscript, rather than the more correct GhostPDL. + +Binaries for Ghostscript and (see below) GhostPDF (included in the Ghostscript binaries) for various systems can be downloaded from `here`_. The source can be found in both the Ghostscript and GhostPDL downloads from the same site. + + + + + +GhostPDF +~~~~~~~~~~~~~~~~ + +Prior to release 9.55.0 GhostPDF was an interpreter for the PDF page description language built on top of Ghostscript, and written in the PostScript programming language. From 9.55.0 onwards there is a new GhostPDF executable, separate from Ghostscript and written in C rather than PostScript. + +This new interpreter has also been integrated into Ghostscript itself, in order to preserve the PDF functionality of that interpreter. For now, the old PostScript-based interpreter remains the default, but the new interpreter is built-in alongside it. + +The intention is that the new interpreter will replace the old one, which will be withdrawn. + +It is possible to control which interpreter is used with the NEWPDF command-line switch. When this is false (the current default) the old PostScript-based interpreter is used, when NEWPDF is true then the new C-based interpreter is used. + + + + + +GhostPDL +~~~~~~~~~~~~~~~~ + +Historically, we’ve used GhostPDL as an umbrella term to encompass our entire line of products. We've now brought all these disparate products together into a single package, called, appropriately enough, GhostPDL. + +When running on a printer (or server) GhostPDL now automatically detects the type of data being fed to it and processes it accordingly. The individual interpreters all plug into a top-level module that handles both automatic language detection and Printer Job Language (PJL) based configuration. + +The exact set of interpreters present in an installation can be tuned by the integrator for their specific product/use cases. + +In addition to our existing PDL modules (PS, PDF, PCL, PXL, and XPS) we have now added new modules to handle a range of common image formats. With these installed, GhostPDL will handle JPEGs (both JFIF and EXIF), PWGs, TIFFs, PNGs, JBIG2s, and JPEG2000s. + +GhostPDL is available both under the `GNU Affero GPL license`_ and for `commercial licensing`_ from `Artifex`_. + +The source code for GhostPDL can be found `here`_. + + + + + +GhostPCL +~~~~~~~~~~~~~~~~ + +GhostPCL is an interpreter for PCL™ and PXL files. This consists of an PCL/PXL interpreter hooked up to the Ghostscript graphics library. + +GhostPCL is available both under the `GNU Affero GPL license`_ and for `commercial licensing`_ from `Artifex`_. + +Binaries for GhostPCL for various systems can be downloaded from `here`_. The source can be found in the GhostPCL/GhostPDL downloads from the same site. + + + + +GhostXPS +~~~~~~~~~~~~~~~~ + +GhostXPS is an interpreter for XPS (XML Paper Specfication) files. This consists of an XPS interpreter hooked up to the Ghostscript graphics library. + +GhostXPS is available both under the `GNU Affero GPL license`_ and for `commercial licensing`_ from `Artifex`_. + +Binaries for GhostXPS for various systems can be downloaded from `here`_. The source can be found in the GhostXPS/GhostPDL downloads from the same site. + + +.. _URWFontInformation: + +URW Font Information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The set of truetype fonts in the urwfonts directory are necessary for the PCL/XL interpreter to function properly but they ARE NOT FREE SOFTWARE and are NOT distributed under the GNU GPL/AGPL. They can instead be redistributed under the `AFPL`_ license which bars commercial use. + +If your copy of GhostPDL includes these fonts, you should have received a copy of the Aladdin Free Public License, usually in a file called COPYING.AFPL. If not, please contact Artifex Software, Inc. 1305 Grant Avenue - Suite 200, Novato, CA 94945 USA, or visit `Artifex`_ + + + + +Document roadmap by theme +----------------------------- + +What should I read if I'm a new user? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- :ref:`How to use Ghostscript<Use.htm>`. This includes both a quickstart introduction to the command line version and more extensive reference material. +- detailed information about :ref:`specific devices<Devices.htm>` that Ghostscript can use for output. +- more detailed information about how to use Ghostscript under Unix with ``lpr`` :ref:`as a filter<Unix-lpr.htm>` for printing. +- for information about known problems or to report a new one, please visit `bugs.ghostscript.com`_ but remember that free versions of Ghostscript come with with NO WARRANTY and NO SUPPORT. + + +GPL and commercial Ghostscript +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +GPL Ghostscript, Artifex Ghostscript and AFPL Ghostscript are different releases. + +- additional information about `GPL Ghostscript releases`_ that is not relevant to commercial versions. + +If you run into any questions, or if you are going to be using Ghostscript extensively, you should at least skim, and probably eventually read: + +- about the :ref:`fonts distributed with Ghostscript<Fonts.htm>`, including how to add or replace fonts. +- a description of :ref:`the Ghostscript language<Language.htm>`, and its differences from the documented PostScript language. +- about the :ref:`postscript files distributed with Ghostscript<Psfiles.htm>` (other than fonts). + + +Before building Ghostscript +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are going to compile Ghostscript from source, rather than just use an executable you got from somewhere, you may want to read: + +- :ref:`How to build Ghostscript<Make.htm>` and :ref:`install it<Install.htm>`. + + +What should I read if I'm *not* a new user? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you have already used Ghostscript, when you receive a new release you should begin by reading this file, then: + +- `News`_, for incompatible changes and new features in the current release. + + +What if I'm a developer? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are going to do any development on or with Ghostscript at all, you should at least look at: + +- the :ref:`roadmap documentation<Develop.htm>` for Ghostscript's source files and architecture. + +If you are going to write a new driver for Ghostscript, you should read: + +- the :ref:`guide to the Ghostscript source code<Source.htm>`. +- the interface between Ghostscript and :ref:`device drivers<Drivers.htm>`. + +If you are considering distributing GPL Ghostscript in conjunction with a commercial product, you should read the `license`_ carefully, and you should also read: + +- additional clarification of the circumstances under which Ghostscript can be distributed with a commercial product. + +If you intend to use Ghostscript in the form of a dynamic link library (DLL) under OS/2 or Microsoft Windows or in the form of shared object under Linux, read: + +- documentation on :ref:`Ghostscript Interpreter API<API.htm>`. + +If you want to use Ghostscript as part of another program, as a callable PostScript language interpreter, and not as a DLL or as a self-contained executable application, you should begin by reading: + +- the source file ``imain.h``, the documented API for Ghostscript not as a DLL. + +or if you are going to use only the Ghostscript graphics library: + +- about the structure of the :ref:`Ghostscript library<Lib.htm>` and its interfaces. + +What if I'm writing documentation? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are editing or adding to Ghostscript's existing documentation you should contact us on our Discord channel or the gs-devel mailing list for guidance, links to those are on: `www.ghostscript.com`_. + + + + + +Presence on the World Wide Web +------------------------------------ + + +Ghostscript's home page +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript has a home page on the World Wide Web with helpful information such as the FAQ (Frequently Asked Questions): + +`www.ghostscript.com`_ + +Adobe PostScript, Encapsulated PostScript, and PDF reference documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adobe makes a wealth of technical documentation available over the Web, including the `PostScript Language Reference Manual (Third Edition)`_ ; the `Encapsulated PostScript`_ (EPS) Format Specification version 3, including :ref:`Encapsulated PostScript Interchange<Ps2epsi.htm>` (EPSI) format; the `PDF Reference manuals`_. The `Acrobat SDK`_ contains `pdfmark and Acrobat Distiller parameters documentation`_. + + +Other material on the WWW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Much other material about Ghostscript is available on the World Wide Web, both as web pages and as archived Usenet and mailing list discussions. Use the well-known search engines to find such material. + + + + +.. External links + +.. _www.ghostscript.com: http://www.ghostscript.com/ +.. _here: http://www.ghostscript.com/download +.. _AGPL: +.. _GNU Affero GPL license: http://www.gnu.org/licenses/agpl-3.0.html +.. _AFPL: https://en.wikipedia.org/wiki/Aladdin_Free_Public_License +.. _commercial licensing: https://artifex.com/licensing/commercial/ +.. _Artifex: https://artifex.com +.. _News: https://ghostscript.com/doc/current/News.htm +.. _bugs.ghostscript.com: https://bugs.ghostscript.com +.. _History#.htm: https://ghostscript.com/doc/current/History9.htm +.. _GPL Ghostscript releases: COPYING +.. _license: COPYING +.. _COPYING: COPYING + +.. _PostScript Language Reference Manual (Third Edition): http://partners.adobe.com/public/developer/en/ps/PLRM.pdf +.. _Encapsulated Postscript: http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf +.. _PDF Reference manuals: http://partners.adobe.com/public/developer/pdf/index_reference.html +.. _Acrobat SDK: http://partners.adobe.com/public/developer/acrobat/sdk/index.html +.. _pdfmark and Acrobat Distiller parameters documentation: http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/SampleDownscaleDevice.rst b/doc/src/SampleDownscaleDevice.rst new file mode 100644 index 00000000..b0812939 --- /dev/null +++ b/doc/src/SampleDownscaleDevice.rst @@ -0,0 +1,142 @@ +.. title:: Sample CMYK 32-bit Device that Supports Post Rendering Processing + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _SampleDownscaleDevice.htm: + + +Sample CMYK 32-bit Device that Supports Post Rendering Processing +===================================================================== + + + + +This device is a basic CMYK 32-bit (8-bits per component) device that uses the downscaler features to provide post-rendering operations on the raster data produced by Ghostscript. + +It is designed to allow a developer to add code to handle the resulting raster data and perform any desired formatting and transmission to some destination, for example DMA to a printer or sending over a network link. + + + +Features +------------ + +The ``downscaler`` modules provide for the following optional post-rendering manipulation: + +``-dDownScaleFactor=factor`` (small non-negative integer; default = 1) + If this option set then the page is downscaled by the given factor on both axes. For example rendering with -r600 and then specifying ``-dDownScaleFactor=3`` will produce a 200dpi image. + + 2 additional "special" ratios are available, 32 and 34. 32 provides a 3:2 downscale (so from 300 to 200 dpi, if the resolution is 300 dpi as with -r300). 34 produces a 3:4 upscale (so from 300 to 400 dpi, similarly). + +``-sPostRenderProfile=path`` (path to an ICC profile) + If this option set then the page will be color transformed using that profile after downscaling. + This is useful when the file uses overprint to separately paint to some subset of the C, M, Y, and K colorants, but the final CMYK is to be color corrected for printing or display. + + +The ``ds32`` device can perform rudimentary automatic bitmap 'trapping' on the final rendered bitmap. This code is disabled by default; see the `Trapping patents`_ below as to why. + +Trapping is a process whereby the output is adjusted to minimise the visual impact of offsets between each printed plane. Typically this involves slightly extending abutting regions that are rendered in different inks. The intent of this is to avoid the unsightly gaps that might be otherwise be revealed in the final printout if the different color plates do not exactly line up. + +This trapping is controlled by 3 device parameters. Firstly the maximum X and Y offsets are specified using: + +``-dTrapX=N`` + +and: + +``-dTrapY=N`` + +(where N is a figure in pixels, before the downscaler is applied). + + +The final control is to inform the trapping process in what order inks should be processed, from darkest to lightest. For a typical CMYK device this order would be [ 3 1 0 2 ] (K darker than M darker than C darker than Y). This is the default. + +To override these defaults, the ``TrapOrder`` parameter can be used. Since this parameter requires an array, it must be specified using a different method. For example, if Cyan is darker than Magenta: + + +.. code-block:: bash + + gs -sDEVICE=ds32 -dTrapX=2 -dTrapY=2 -c "<< /TrapOrder [ 3 0 1 2 ] >> setpagedevice" -f examples\colorcir.ps + + +Trapping patents +~~~~~~~~~~~~~~~~~~~ + +Trapping is an technology area encumbered by many patents. Until we can convince ourselves that our trapping code is not covered by any of these patents, the functionality is disabled by default. + +It can be enabled by building with the ``ENABLE_TRAPPING`` define, but before you do so you should convince yourself that either: + +- The trapping code is not covered by any existing patent. +- Any patents that do cover the code are invalid in your jurisdiction. +- That you have appropriate patent licenses for any patents that do apply. + +You bear full responsibility for choosing to build with ``ENABLE_TRAPPING``. + + + + + + +Changes to devices/devs.mak +-------------------------------- + +The make files used to build Ghostscript use the file ``devices/devs.mak`` to describe what is needed for devices that can be built into the executable, such as source code files, header files, libraries and dependencies on other parts of Ghostscript. + +The section below can be added to the end of the ``devices/devs.mak`` file: + +.. code-block:: bash + + ### -------- Example 32-bit CMYK downscaled device --------------------- ### + # NB: downscale_ is standard in the lib (LIB1s) + $(DD)ds32.dev : $(DEVOBJ)gdevds32.$(OBJ) $(GLD)page.dev \ + $(GDEV) $(DEVS_MAK) $(MAKEDIRS) + $(SETPDEV2) $(DD)ds32 $(DEVOBJ)gdevds32.$(OBJ) + $(ADDMOD) $(DD)ds32 -include $(GLD)page + + $(DEVOBJ)gdevds32.$(OBJ) : $(DEVSRC)gdevds32.c $(gsicc_cache_h) $(gxdownscale_h) $(AK) \ + $(arch_h) $(gdevprn_h) $(stdio__h) $(stdint__h) $(DEVS_MAK) $(MAKEDIRS) + $(DEVCC) $(DEVO_)gdevds32.$(OBJ) $(C_) $(DEVSRC)gdevds32.c + + + +This snippet is also in a commented block at the top of the source code file. + + + + +Building Ghostscript with the driver +----------------------------------------- + +The make system also needs to be told to include the ``ds32`` device. This can either be added to the top level make file on one of the ``DEVICE_DEVS`` lines, for example, in ``psi/msvc.mak`` for the Windows build: + +.. code-block:: bash + + DEVICE_DEVS21=$(DD)ds32.dev $(DD)spotcmyk.dev $(DD)devicen.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)cp50.dev $(DD)gprf.dev + + +Rather than editing a make file, there is a convenient macro that allows the extra device to be added to the build command line, ``DEVICE_DEVS_EXTRA``. + +For example, on linux: + +.. code-block:: bash + + make DEVICE_DEVS_EXTRA=obj/ds32.dev + +or, on Windows: + +.. code-block:: bash + + nmake -f psi/msvc32.mak DEVICE_DEVS_EXTRA=obj\ds32.dev + + +Source code +------------- + +The source for this device driver is in: ``doc/gdevds32.c`` + + + + + +.. include:: footer.rst diff --git a/doc/src/SavedPages.rst b/doc/src/SavedPages.rst new file mode 100644 index 00000000..8cdca4fa --- /dev/null +++ b/doc/src/SavedPages.rst @@ -0,0 +1,171 @@ +.. title:: Using Saved Pages + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _SavedPages.htm: + + +Using Saved Pages +========================================== + + + + + +Saved pages can be printed in any order, any number of times allowing for copy collation, manual 'duplex' printing or selecting a subset of pages. + +Many raster printing devices and raster image format devices can use the command list (clist) to save the rendering information into files or memory based structures. Usually the clist data is rendered as soon as the page is complete, but it is` possible to defer rendering, then output (print) after the entire file has been converted to clist files. + +Since each page is saved separately, the pages can be rendered from the clist files in any order, any number of times. + +The saved pages are accumulated in clist form as files or in memory. The default clist storage is specified by the ``BAND_LIST_STORAGE=`` macro in the make file, but if ``BAND_LIST_STORAGE=file``, the clist can be forced to be in memory using the ``-sBandListStorage=memory`` option. + + + + + + + +Saved Pages control keywords +--------------------------------- + +Deferring printing is controlled using the ``--saved-page=...`` option. + +The string following the ``--saved-page=`` consists of keywords, separated by white-space, commas, or other non-alphanumeric characters such as '``:``', '``=``', '``;``'. If more than one keyword is given, the string should be enclosed in double-quotes ("). + +The '``-``' (dash), and the '``*``' asterisk), are used in page range selections, and cannot be keyword separators. + +Keywords are case independent, thus ``begin``, ``BEGIN``, and ``Begin`` are all equivalent. + +``begin`` + Begins accumulating pages to a list. The clist data for each page is saved in files or memory as discussed above, but no rendering is performed. + If the device was set for rendering into memory, is will be switched to accumulating the page as clist files, thus ``-dMaxBitmap`` and ``-dBandingNever`` will be ignored, as if ``-dBandingAlways`` was specified. + +``flush`` + Delete all clist files for all pages on the list, and reset the list to empty, but remain in ``saved-pages`` mode. Subsequent pages will be added to the list. + +``end`` + Flush any list, deleting all clist files for any accumulated pages and stop accumulating pages, returning to rendering/output as soon as the page is complete. + + The device may render subsequent pages in memory (page buffer) as determined by ``-dMaxBitmap`` and ``-dBandingNever``. + + +``copies`` *copy_count* + Set the copy count for the print action. The requested number of copies will be generated for all subsequent print actions, thus producing collated copies, rather than multiple copies of each page as in normal (non-deferred) rendering and output. + + A ``--saved-pages="copies #"`` option will be applied to all print actions until a new copies # is encountered that sets the copy count to a different value. Since the copies can follow the print command, it is recommended that only a single copies be in a each ``--saved-pages=...`` string. + + .. note:: + + Unless ``-d.IgnoreNumCopies=true`` is specified prior to starting ``saved-pages`` mode, the copy count for each page will be saved with each page, and the job will contain the specified number of copies of each page, as well as producing the number of collated copies of the job set by the copies in a ``--saved-pages=...`` string. + +``print`` *print keywords* + Print from the list of saved pages. The print keywords following the print action keyword determine what is printed, and in what order. The keywords are described in the next section. + + +Printing Saved Pages +~~~~~~~~~~~~~~~~~~~~~~~~ + +The string following the print action keyword determines which pages from the list are printed, in what order. Any sequence of keywords, page numbers or page ranges can follow the print keyword. The first control keyword (other than copies) ends the list of printing keywords. + +As with control keywords, print keywords can be any mixture of upper or lower case, and print keyword, page numbers and page ranges can be seperated by any non-alphanumeric character other than '``-``' or '``*``'. + +The following are all equivalent: + + +.. code-block:: + + 1 3 5 - * + 1, 3, 5-* + 1,3,5-* + + +``copies`` *copy_count* + As mentioned above, the copies keyword and count can follow the print keyword. See the description of the copies keyword in the previous section. + The copy count will be applied to the entire sequence of print keywords, so it can appear anywhere in the sequence of page number, page ranges or print keywords. + +``normal`` + Print all of the pages, from the first until the last page in the list. This keyword is used to print collated copies in the usual page order. This is the same as the page range: "``1 - *``" + +``reverse`` + Print all of the pages, from the last backwards to the first page in the list. This keyword is used to print collated copies in the reverse page order. This is the same as the page range: "``* - 1``" + +``odd`` + Print all odd number pages, from 1 to the last odd numbered page. This keyword, combined with the even keyword and user interaction to place pages that were printed into the input tray, can be used for manual duplexing. + +``even`` + Print all even number pages, from 2 to the last even numbered page, then if the list has an odd number of pages print a blank 'pad' page to be the back of the last odd page. This keyword, combined with the odd keyword and user interaction to place pages that were printed into the input tray, can be used for manual duplexing. + +``even0pad`` + Print all even number pages, from 2 to the last even numbered page, without any blank 'pad' page as with the even keyword. + +*page_number* + A number not followed by '``-``' specifies a single page from the list to be printed. The '``*``' character represents the last page in the list, interpreted as a number, either as a single *page_number* or as the *start_page* or *end_page* in a page range. + +*start_page - end_page* + A range of pages is two *page_numbers* or ``*`` separated by a '``-``', optionally surrounded by non-alphanumeric characters other than '``-``' which is a special character in page range specifications. The pages from the *start_page* to the *end_page* are printed. + + If the *start_page* is after the *end_page*, then the order of the pages is reversed, from the *start_page* back to the *end_page*. + + +Examples +---------------- + +The following examples each print 2 collated copies from the first page to the last page: + + +.. code-block:: bash + + --saved-pages="print: normal, copies=2" + --saved-pages="print copies=2, normal" + --saved-pages="copies 2 print normal" + --saved-pages="print 1-* 1-*" + --saved-pages="print normal normal" + + +Print the last page, followed by all pages in reverse order, then the first page (print reverse with two copies of the last and first page): + +.. code-block:: bash + + --saved-pages="print * reverse 1" + +or: + +.. code-block:: bash + + --saved-pages="print * * - 1 1" + + +Using the command line arguments with a PostScript or PDF input file to print the odd pages, prompt the operator to reload the printer with the pages that were printed, then print the even pages: + + +.. code-block:: bash + + gs -sDEVICE=pgmraw -o /dev/lp0 --saved-pages="begin" examples/annots.pdf \ + --saved-pages="print odd" \ + -c "(Move printed pages to the input tray, then press enter.) = flush \ + (%stdin) (r) file 256 string readline clear" \ + --saved-pages="print even" + + +Print two collated copies of the first file, followed by 5 copies of the second file: + + +.. code-block:: bash + + gs -sDEVICE=pgmraw -o /dev/lp0 --saved-pages="begin" examples/annots.pdf \ + --saved-pages="copies=2 print normal flush" \ + examples/colorcir.ps \ + --saved-pages="copies=5 print normal" + + + + + + + + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/Source.rst b/doc/src/Source.rst new file mode 100644 index 00000000..ba3c9cc3 --- /dev/null +++ b/doc/src/Source.rst @@ -0,0 +1,222 @@ +.. title:: Guide to Ghostscript Source Code + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Source.htm: + + +Guide to Ghostscript Source Code +=================================== + + +Conceptual overview +------------------------ + +The Ghostscript source code is divided conceptually as follows: + +**PostScript interpreter** + +.. list-table:: + :header-rows: 0 + :widths: 50 50 + + * - PostScript operators + - ``z*.h`` and ``z*.c`` + * - Other interpreter code + - ``i*.h`` and ``i*.c`` + * - PostScript code + - ``gs_*.ps`` + + +**PDF interpreter** + + +.. list-table:: + :header-rows: 0 + :widths: 50 50 + + * - PostScript code + - ``pdf_*.ps`` + + + +**Graphics library** + +.. list-table:: + :header-rows: 0 + :widths: 50 50 + + * - Main library code + - ``g*.h`` and ``g*.c`` + * - Streams + - ``s*.h`` and ``s*.c`` + * - `Device drivers`_ + - ``gdev*.h`` and ``gdev*.c`` + * - `Platform-specific code`_ + - ``gp*.h`` and ``gp*.c`` + + + +PostScript interpreter +------------------------ + +``gs.c`` is the main program for the interactive language interpreter; ``gserver.c`` is an alternative main program that is a rudimentary server. If you configure Ghostscript as a server rather than an interactive program, you will use ``gserver.c`` instead of ``gs.c``. + +Files named ``z*.c`` are Ghostscript operator files. The names of the files generally follow the section headings of the operator summary in section 6.2 (Second Edition) or 8.2 (Third Edition) of the PostScript Language Reference Manual. Each operator ``XXX`` is implemented by a procedure named ``zXXX``, for example, ``zfill`` and ``zarray``. + +Files named ``i*.c``, and ``*.h`` other than ``g*.h``, are the rest of the interpreter. See the ``makefile`` for a little more information on how the files are divided functionally. + +The main loop of the PostScript interpreter is the interp procedure in ``interp.c``. When the interpreter is reading from an input file, it calls the token scanner in ``iscan*.c``. + +``idebug.c`` contains a lot of debugger-callable routines useful for printing PostScript objects when debugging. + + +PDF interpreter +-------------------- + +The PDF interpreter is written entirely in PostScript. Its main loop is the ``.pdfrun`` procedure in ``pdf_base.ps``. When the PDF interpreter is configured into the build, it redefines the "run" operator to test whether the file is a PDF file. This redefinition is near the beginning of ``pdf_main.ps``. + + + +Graphics library +------------------ + +Files beginning with ``gs``, ``gx``, or ``gz`` (both ``.c`` and ``.h``), other than ``gs.c`` and ``gserver.c``, are the Ghostscript library. Files beginning with ``gdev`` are device drivers or related code, also part of the library. Other files beginning with ``g`` are library files that don't fall neatly into either the kernel or the driver category. + +Files named ``s*.c`` and ``s*.h`` are a flexible stream package, including the Level 2 PostScript "filters" supported by Ghostscript. See ``stream.h``, ``scommon.h``, and ``strimpl.h`` for all the details. + + +Device drivers +~~~~~~~~~~~~~~~~~~ + +The interface between the graphics library and device drivers is the only really well documented one in all of Ghostscript: see the :ref:`documentation on drivers<Drivers.htm>`. + +In addition to many real device and file format drivers listed in ``devs.mak`` and ``contrib.mak``, a number of drivers are used for internal purposes. You can search ``lib.mak`` for files named ``gdev*.c`` to find almost all of them. + +Drivers are divided into "printer" drivers, which support banding, and non-printer drivers, which don't. The decision whether banding is required is made (by default on the basis of how much memory is available) in the procedure ``gdev_prn_alloc`` in ``gdevprn.c``: it implements this decision by filling the virtual procedure table for the printer device in one of two different ways. + +A good simple "printer" (bandable) driver to read is ``gdevmiff.c``: it's less than 100 lines, of which much is boilerplate. There are no simple non-printer drivers that actually drive devices: probably the simplest non-printer driver for reading is ``gdevm8.c``, which implements 8-bit-deep devices that only store the bits in memory. + + +Platform-specific code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are very few platform dependencies in Ghostscript. Ghostscript deals with them in three ways: + +Files named ``*_.h`` substitute for the corresponding ``<*.h>`` file by adding conditionals that provide a uniform set of system interfaces on all platforms. + +The file ``arch.h`` contains a set of mechanically-discovered platform properties like byte order, size of int, etc. These properties, not the names of specific platforms, are used to select between different algorithms or parameters at compile time. + +Files named ``gp*.h`` define interfaces that are intended to be implemented differently on each platform, but whose specification is common to all platforms. + +The platform-specific implementations of the ``gp*.h`` interfaces have names of the form ``gp_{platform}.c``, specifically (this list may be out of date): + + +**Platform-specific interfaces** + + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Routine + - Platform + * - ``gp_dosfb.c`` + - DOS + * - ``gp_dosfs.c`` + - DOS and MS Windows + * - ``gp_itbc.c`` + - DOS, Borland compilers + * - ``gp_iwatc.c`` + - DOS, Watcom or Microsoft compiler + * - ``gp_msdos.c`` + - DOS and MS Windows + * - ``gp_ntfs.c`` + - MS Windows NT + * - ``gp_os2.c`` + - OS/2 + * - ``gp_os9.c`` + - OS-9 + * - ``gp_unifs.c`` + - Unix, OS-9, and QNX + * - ``gp_unix.c`` + - Unix and QNX + * - ``gp_vms.c`` + - VMS + * - ``gp_win32.c`` + - MS Windows NT + +If you are going to extend Ghostscript to new machines or operating systems, check the ``*_.h`` files for ``ifdef`` on things other than ``DEBUG``. You should probably plan to make a new ``makefile`` and a ``new gp_XXX.c`` file. + + + + +Makefiles +--------------------------------------- + +This section is only for advanced developers who need to integrate Ghostscript into a larger program at build time. + +.. note :: + + THIS SECTION IS INCOMPLETE. IT WILL BE IMPROVED IN A LATER REVISION. + + +The Ghostscript ``makefiles`` are meant to be organized according to the following two principles: + +#. All the parameters that vary from platform to platform appear in the top-level ``makefile`` for a given platform. ("Platform" = OS + compiler + choice of interpreter vs. library). + +#. All the rules and definitions that can meaningfully be shared among more than 1 platform appear in a ``makefile`` that is "included" by a ``makefile`` (normally the top-level ``makefile``) for those platforms. + +Thus, for example: + +- Rules and definitions shared by all builds are in ``gs.mak``. + +- Rules and definitions specific to the library (on all platforms) are in ``lib.mak``. In principle this could be merged with ``gs.mak``, but we wanted to leave open the possibility that ``gs.mak`` might be useful with hypothetical interpreter-only products. + +- Stuff specific to interpreters (on all platforms) is in ``int.mak``. +- Stuff specific to all Unix platforms should be in a single ``unix.mak`` file, but because make sometimes cares about the order of definitions, and because some of it is shared with DV/X, it got split between ``unix-aux.mak``, ``unix-end.mak``, ``unixhead.mak``, ``unixinst.mak``, and ``unixlink.mak``. + +For MS-DOS and MS Windows builds, there should be: + + +- A ``makefile`` for all MS OS (DOS or Windows) builds, for all compilers and products. + + Perhaps a ``makefile`` for all MS-DOS builds, for all compilers and products, although since Watcom is the only such compiler we're likely to support this may be overkill. + +- A ``makefile`` for all MS Windows builds, for all compilers and products. + +- A ``makefile`` for all Watcom builds (DOS or Windows), for all products. + +- A top-level ``makefile`` for the Watcom DOS interpreter product. + +- A top-level ``makefile`` for the Watcom Windows interpreter product. + +- A top-level ``makefile`` for the Watcom DOS library "product". + +- A top-level ``makefile`` for the Watcom Windows library "product". + +- A ``makefile`` for all Borland builds (DOS or Windows), for all products. + + +and so on. + + + + + + + + + + + + + + + + + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/Unix-lpr.rst b/doc/src/Unix-lpr.rst new file mode 100644 index 00000000..7b58b726 --- /dev/null +++ b/doc/src/Unix-lpr.rst @@ -0,0 +1,121 @@ +.. title:: Setting Up a Unix lpr Filter for Ghostscript + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Unix-lpr.htm: + + + +Setting Up a Unix lpr Filter for Ghostscript +============================================== + + + +*"How do I set up Ghostscript to provide PostScript queues in a standard lpr environment on Unix systems?"* is a Frequently Asked Question amongst Ghostscript users. The two shell scripts described by this document are designed to make this task a little easier. They are: + + +``unix-lpr.sh`` + a flexible, multi-option print filter. + +``lprsetup.sh`` + A shell script which sets up soft links and creates a template insert for the ``printcap`` file. + + +What it can do +---------------------- + +The print filter resides in the Ghostscript installation directory (often ``/usr/local/share/ghostscript``, but may be something else at your installation), together with a dummy filter directory containing various soft links which point to the filter. It offers the following features: + +- Multiple devices supported by a single filter. + +- Multiple bit-depths for the same device. + +- Multiple number of colours for the same device. + +- Direct (single-queue) and indirect (two-queue) setup. + +- Support for the standard preprocessing filters if you have the corresponding (whatever)-to-PostScript translators. + +- Redirection of diagnostic and programmed output to a ``logfile`` in the spooling directory. + +- Maintaining of printer accounting records of the numbers of pages printed by each user (compatible with the ``pac`` command). + +- Straightforward editing for further customisation. + + +Setting it up +--------------- + +The ``lprsetup.sh`` script needs to have two lines edited before running, to set the printer devices to use and the list of filters available. With this information, it: + +- Creates a "filt" subdirectory under the Ghostscript installation directory. + +- Creates the links in this directory which enable the filter to determine the parameters for running Ghostscript. + +- Automatically generates ``printcap`` entries which should need only a little editing before adding to your system ``printcap`` file. + + +Editing the device list DEVICES +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +At the top of ``lprsetup.sh`` is a line of the form ``DEVICES={list}``. Replace the example list with your own list of devices. Each entry is the name of a device, followed by three more optional fields, separated by dots "``.``". + + +.. _field-bits-per-pixel: + +Field 1: bits per pixel +"""""""""""""""""""""""" + +The first field is required only if the printer device understands the ``-dBitsPerPixel=`` switch, which applies only to colour devices. For a particular number N of bits per pixel, add the suffix ``.N`` to the device name, for instance ``cdj500.3``, ``cdj500.24``, etc. + +Field 2: colours +"""""""""""""""""""""""" + +The second field is required only if the printer device understands the setting of the Colors device parameter (as in ``-dColors=``), which applies only to colour devices (and at present is only supported by the ``bjc*`` family of drivers). For a particular number N of colours, suffix ``.N`` to the device name, such as ``bjc600.24.3``, ``bjc600.8.1`` etc. + + +.. _field_dq: + +Field 3: dual queues +"""""""""""""""""""""""" + +The third field is required in order to use two separate queues for the device, a "raw" queue and a PostScript queue (see `Single or dual queues`_ below). If you want dual queues, add the suffix ``.dq`` ("dual queue") to the name, whether or not a :ref:`bits-per-pixel<field-bits-per-pixel>` suffix has already been added. + + +Example definition of DEVICES +"""""""""""""""""""""""""""""""""""""""""""""""" + +Thus the following list supports a :title:`cdj550` device at three different bit depths (24 bpp, 3 bpp and 1 bpp), with a dual queue (that is, a separate queue for the raw data); a monochrome deskjet device with a single queue; and a :title:`djet500` device using a separate queue: + + +.. code-block:: postscript + + DEVICES="cdj550.24.dq cdj550.3.dq cdj550.1.dq deskjet djet500.dq" + +Editing the filter list +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The standard list contains only the generic "``if``" filter, but a commented-out list shows other filters which may be available. If you wish to use the support for these filters, you may need to edit the ``bsd-if`` file to add to the ``PATH`` the directories where the translators are stored, or to change the names of the filters if yours are different. The ``bsd-if`` script is supplied with an example setup using Transcript (a commercial package from Adobe), and ``PBMPLUS``, a freeware package by Jef Poskanzer and others. + +Editing the printer port and type +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can set the port and port type (parallel or printer) for an attached printer, but for remote printers you'll have to modify the ``printcap.insert`` file yourself. + +Modifying printcap.insert +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Running ``lprsetup.sh`` generates a file ``printcap.insert`` which has a template setup for your printer queues. It cannot guarantee to do the whole job, and you will probably need to consult your system documentation and edit this file before you add it to your ``printcap`` file. The file has good defaults for serial printers, as these often cause problems in getting binary data to the printer. However, you may need to change the baud rate, or the handshaking method. Only a small change is required in the ``printcap`` file to use a networked remote printer instead of an attached printer, and an example is given in ``printcap.insert``. + +Single or dual queues +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you wish to provide a PostScript-only queue (for example, so that all pages printed go through accounting), and the printer port is local to the host machine, a single queue is appropriate -- Ghostscript simply converts PostScript into the printer's native data format and sends it to the port. But if the printer is on a remote networked machine, or if you need to send raw printer data to the printer, you must use two queues. Simply specify the :ref:`dq<field_dq>` option above. + + + + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/UnsupportedDevices.rst b/doc/src/UnsupportedDevices.rst new file mode 100644 index 00000000..b7b2c12f --- /dev/null +++ b/doc/src/UnsupportedDevices.rst @@ -0,0 +1,4208 @@ +.. title:: Unsupported devices + + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _UnsupportedDevices.htm: + + + +Unsupported devices +=================================== + + + + +These devices are no longer supported and/or superceeded by newer methods. The documentation is kept here for reference. Be advised that these devices will be removed in future versions of Ghostscript. + +Supported devices are descripted in :ref:`Details of Ghostscript output devices<Devices.htm>`. + +For other information, see the :ref:`Ghostscript overview<Readme.htm>`. You may also be interested in :ref:`how to build Ghostscript<Make.htm>` and :ref:`install it<Install.htm>`, as well as the description of the :ref:`driver interface<Drivers.htm>`. + + + + + + + +H-P 8xx, 1100, and 1600 color inkjet printers +---------------------------------------------------- + +This section, written by `Uli Wortmann`_, deals with the DeskJet 670, 690, 850, 855, 870, 890, 1100, and 1600. + + + +Drivers contained in ``gdevcd8.c`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The source module ``gdevcd8.c`` contains four generic drivers: + + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - :title:`cdj670` + - HP DeskJet 670 and 690 + * - :title:`cdj850` + - HP DeskJet 850, 855, 870, and 1100 + * - :title:`cdj890` + - HP DeskJet 890 + * - :title:`cdj1600` + - HP DeskJet 1600 + + +Further documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Credits: Much of the driver is based on ideas derived from the :title:`cdj550` driver of George Cameron. The support for the hp670, hp690, hp890 and hp1600 was added by Martin Gerbershagen. + + +.. list-table:: + :widths: 10 20 70 + :header-rows: 1 + + * - Date + - Version + - Comments + * - 11.11.96 + - Version 1.0 + - + * - 25.08.97 + - Version 1.2 + - Resolved all but one of the known bugs, + + introduced a couple of perfomance improvements. + + Complete new color-transfer-function handling (see gamma). + + * - 01.06.98 + - Version 1.3 + - Due to the most welcome contribution of + + `Martin Gerbershagen`_, support for the + + hp670, hp690 and hp890 + + and hp1600 has been added. + + Martin has also resolved all known bugs. + + Problems: Dark colors are still pale. + + +The hp690 is supported through the hp670 device, the hp855, hp870 and the hp1100 through the hp850 device. The driver needs no longer special switches to be invoked except ``-sDEVICE=cdj850``, ``-sDEVICE=CDJ890``, ``-sDEVICE=CDJ670``, or ``-sDevice=CDJ1600``. The following switches are supported: + + +.. list-table:: + :widths: 30 20 50 + :header-rows: 0 + + * - ``-dPapertype=`` + - 0 + - plain paper [default] + * - + - 1 + - bond paper + * - + - 2 + - special paper + * - + - 3 + - glossy film + * - + - 4 + - transparency film + * - + - + - Currently the lookup tables are unsuited for printing on special + + paper or transparencies. For these please revert to the gamma functions. + + * - ``-dQuality=`` + - -1 + - draft + * - + - 0 + - normal [default] + * - + - 1 + - presentation + * - ``-dRetStatus=`` + - 0 + - C-RET off + * - + - 1 + - C-RET on [default] + * - ``-dMasterGamma=`` + - 3.0 + - [default = 1.0] + + +.. note:: + + To take advantage of the calibrated color-transfer functions, be sure not to have any gamma statements left! If you need to (i.e., for overhead transparencies), you still can use the gamma functions, but they will override the built-in calibration. To use gamma in the traditional way, set ``MasterGamma`` to any value greater than 1.0 and less than 10.0. To adjust individual gamma values, you have to additionally set ``MasterGamma`` to a value greater than 1.0 and less than 10.0. With the next release, gamma functions will be dropped. + + +When using the driver, be aware that printing at 600dpi involves processing large amounts of data (> 188MB !). Therefore the driver is not what you would expect to be a fast driver ;-) This is no problem when printing a full-sized color page (because printing itself is slow), but it's really annoying if you print only text pages. Maybe I can optimize the code for text-only pages in a later release. Right now, it is recommended to use the highest possible optimisation level your compiler offers. For the time being, use the :title:`cdj550` device with ``-sBitsPerPixel=3`` for fast proof prints. If you simply want to print 600dpi BW data, use the cdj550 device with ``-sBitsPerPixel=8`` (or 1). + +Since the printer itself is slow, it may help to set the process priority of the gs process to "regular" or even less. On a 486/100MHz this is still sufficient to maintain a continuous data flow. Note to OS/2 users: simply put the gs window into the background or minimize it. Also make sure that ``print01.sys`` is invoked without the ``/irq`` switch (great speed improvement under Warp4). + +The printer default settings compensate for dot-gain by a calibrated color-transfer function. If this appears to be too light for your business graphs, or for overhead transparencies, feel free to set ``-dMasterGamma=1.7``. Furthermore, you may tweak the gamma values independently by setting ``-dGammaValC``, ``-dGammaValM``, ``-dGammaValY`` or ``-dGammaValK`` (if not set, the values default to ``MasterGamma``). This will only work when ``-dMasterGamma`` is set to a value greater than 1.0. + +Depending on how you transfer the files, under UNIX you may need to remove the CRs of the CR-LF sequence used for end-of-line on DOS-based (MS Windows-based) systems. You can do this in unpacking the files with ``unzip -a hp850.zip``. + +To compile with ``gs5.x`` or later, simply add to your ``makefile``: + + +.. code-block:: bash + + DEVICE_DEVS4=cdj850.dev cdj670.dev cdj890.dev cdj1600.dev + + + + + +H-P 812, 815, 832, 880, 882, 895, and 970 color inkjet printers +------------------------------------------------------------------------- + +This section, written by `Matthew Gelhaus`_, deals with the DeskJet 812, 815, 832, 880, 882, 895, and 970. + +This is a modified version of the HP8xx driver written by `Uli Wortmann`_. More information and download are available at `gelhaus.net/hp880c`_. + + + + +Drivers contained in ``gdevcd8.c`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The source module ``gdevcd8.c`` contains one generic driver: + + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - :title:`cdj880` + - HP DeskJet 812, 815, 832, 880, 882, 895, and 970 + + + +Further documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Credits: This driver is based on the :title:`cdj850` driver by Uli Wortmann, and shares the same internal structure, although the PCL3+ interpretation has changed. + +.. list-table:: + :widths: 10 20 70 + :header-rows: 1 + + * - Date + - Version + - Comments + * - 15.03.99 + - Version 1.3 + - Initial version, based on Version 1.3 of Uli Wortmann's driver. + * - 26.02.00 + - Version 1.4beta + - Greatly improved color handling & dithering, but not yet complete enough to use for text. + + +All printers are supported through the cdj880 device. Invoke with ``-sDEVICE=cdj880``. The following switches are supported: + + +.. list-table:: + :widths: 30 20 50 + :header-rows: 0 + + * - ``-dPapertype=`` + - 0 + - plain paper [default] + * - + - 1 + - bond paper + * - + - 2 + - special paper + * - + - 3 + - glossy film + * - + - 4 + - transparency film + * - + - + - Currently the lookup tables are unsuited for printing on special + + paper or transparencies. For these please revert to the gamma functions. + + * - ``-dQuality=`` + - -1 + - draft + * - + - 0 + - normal [default] + * - + - 1 + - presentation + * - ``-dMasterGamma=`` + - 3.0 + - [default = 1.0] + + + +The printer default settings compensate for dot-gain by a pre-defined color-transfer function. If this appears to be too light for your business graphs, or for overhead transparencies, feel free to set ``-dMasterGamma=1.7``. Furthermore, you may tweak the gamma values independently by setting ``-dGammaValC``, ``-dGammaValM``, ``-dGammaValY`` or ``-dGammaValK`` (if not set, the values default to ``MasterGamma``). This will only work when ``-dMasterGamma`` is set to a value greater than 1.0. + +To compile with ``gs6.x`` or later, simply add to your ``makefile``: + + +.. code-block:: bash + + DEVICE_DEVS4=$(DD)cdj880.dev + + + + +H-P color inkjet printers +-------------------------------- + +This section, written by George Cameron, deals with the DeskJet 500C, DeskJet 550C, PaintJet, PaintJet XL, PaintJet XL300, the DEC LJ250 operating in PaintJet-compatible mode. + +Drivers contained in ``gdevcdj.c`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The source module ``gdevcdj.c`` contains six generic drivers: + + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - :title:`cdj500` + - HP DeskJet 500C and 540C + * - :title:`cdj550` + - HP DeskJet 550C, 560C, 660C, 660Cse + * - :title:`pjxl300` + - HP PaintJet XL300, DeskJet 1200C, and CopyJet + * - ``pjtest`` + - HP PaintJet + * - ``pjxltest`` + - HP PaintJet XL + * - :title:`declj250` + - DEC LJ250 + +All these drivers have 8-bit (monochrome), 16-bit and 24-bit (colour) and for the DJ 550C, 32-bit (colour, CMYK mode) options in addition to standard colour and mono drivers. It is also possible to set various printer-specific parameters from the command line, for example: + + +.. code-block:: bash + + gs -sDEVICE=cDeskJet -dBitsPerPixel=16 -dDepletion=1 -dShingling=2 tiger.eps + + +.. note :: + + The old names :title:`cdeskjet`, :title:`cdjcolor` and :title:`cdjmono` drivers have been retained; however, their functionality duplicates that available using the drivers above (and :title:`cdeskjet` is identical to :title:`cdj500`). That is, we can use: + + .. code-block:: bash + + gs -sDEVICE=cdj500 -dBitsPerPixel=24 for cdjcolor, and + gs -sDEVICE=cdj500 -dBitsPerPixel=1 for cdjmono + + +Default paper size +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the preprocessor symbol A4 is defined, the default paper size is ISO A4; otherwise it is U.S. letter size (see about :ref:`paper sizes<Known paper sizes>` in the usage documentation). You can :ref:`specify other paper sizes<Use_PaperSize>` on the command line, including A3 for the PaintJet XL and PaintJet XL300, as also explained in the :ref:`usage documentation<Use.htm>`. + +DeskJet physical limits +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The DeskJet's maximum printing width is 2400 dots, or 8 inches (20.32cm). The printer manuals say that the maximum recommended printing height on the page is 10.3 inches (26.16cm), but since this is obviously not true for A4 paper, and I have been unable to detect any problems in printing longer page lengths, this would seem to be a rather artificial restriction. + +All DeskJets have 0.5 inches (1.27cm) of unprintable bottom margin, due to the mechanical arrangement used to grab the paper. Side margins are approximately 0.25 inches (0.64cm) for U.S. letter paper, and 0.15 inches (0.38cm) for A4. + +Printer properties (command-line parameters) +""""""""""""""""""""""""""""""""""""""""""""""""""" + +Several printer "properties" have been implemented for these printers. Those available so far are all integer quantities, and thus may be specified, for instance, like + +.. code-block:: bash + + gs -dBitsPerPixel=32 -dShingling=1 ... + +which sets the ``BitsPerPixel`` parameter to 32 and the ``Shingling`` parameter to 1. + + +Bits per pixel +""""""""""""""""""""""""""""""""""""""""""""""""""" + +If the preprocessor symbol ``BITSPERPIXEL`` is defined as an integer (see below for the range of allowable values), that number defines the default bits per pixel (bit depth) for the generic drivers. If the symbol is undefined, the default is 24 bits per pixel. It is, of course, still possible to specify the value from the command line as described below. Note also that the cDeskJet, cdjcolor and cdjmono drivers are unaffected by setting this symbol, as their default settings are predefined to be 1, 3 and 24 respectively. + +All of the drivers in ``gdevcdj.c`` accept a command line option to set the ``BitsPerPixel`` property. This gives considerable flexibility in choosing various tradeoffs among speed, quality, colour, etc. The valid numbers are: + + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - BITSPERPIXEL + - Comments + * - 1 + - A standard Ghostscript monochrome driver, using black + + ink (by installing the separate mono cartridge in the + + case of the DeskJet 500C, or automatically for the other printers). + * - 3 + - A standard Ghostscript colour driver, using internal dithering. + + This is fast to compute and to print, but the clustered + + dithering can lose some detail and colour fidelity. + * - 8 + - An "error-diffusion" monochrome driver which uses Floyd-Steinberg + + dithering to print greyscale images. + + The patterns are much more randomised than with the normal + + clustered dithering, but the data files can be much larger + + and somewhat slower to print. + * - 16 + - A "cheaper" version of the 24-bit driver, which generates + + Floyd-Steinberg colour dithered output using the minimum + + memory (this may be helpful when using Ghostscript has not + + been compiled using a 16-bit build environment). + + The quality can be almost as good as the 24-bit version. + * - 24 + - A high-quality colour driver using Floyd-Steinberg + + dithering for maximum detail and colour range. + + However, it is very memory-intensive, and thus can + + be slow to compute. It tends to produce rather + + larger raw data files, so they can also take longer to print. + * - 32 + - Only for the DeskJet 550C, which uses the black cartridge + + and the colour cartridge simultaneously (that is, CMYK printing). + + This printer can both be faster and give higher quality than + + the DeskJet 500C, because of the true black ink. + + (Note that the 24-bit mode also permits CMYK printing on + + this printer, and uses less memory). Any differences + + between 24-bit and 32-bit should be small. + + +DeskJet properties +""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. list-table:: + :widths: 30 10 60 + :header-rows: 1 + + * - Name + - Type + - Comments + * - BlackCorrect + - `int` + - Colour correction to give better blacks when using + + the DJ500C in colour mode. For example, the + + default of 4 reduces the cyan component to 4/5. + + Range accepted: 0 - 9 (0 = none). + * - Shingling + - `int` + - Interlaced, multi-pass printing: + + 0 = none, 1 = 50%, 2 = 25%, 2 is best and slowest. + * - Depletion + - `int` + - "Intelligent" dot-removal: + + 0 = none, 1 = 25%, 2 = 50%, 1 best for graphics? + + Use 0 for transparencies. + +PaintJet XL300 / PaintJet XL properties +""""""""""""""""""""""""""""""""""""""""""""""""""" + + +.. list-table:: + :widths: 30 10 60 + :header-rows: 1 + + * - Name + - Type + - Comments + * - PrintQuality + - `int` + - Mechanical print quality: -1 = fast, 0 = normal, 1 = presentation. + + Fast mode reduces ink usage and uses single-pass operation for + + some media types. Presentation uses more ink and the maximum number + + of passes, giving slowest printing for highest quality. + * - RenderType + - `int` + - 0 driver does dithering + + 1 snap to primaries + + 2 snap black to white, others to black + + 3 ordered dither + + 4 error diffusion + + 5 monochrome ordered dither + + 6 monochrome error diffusion + + 7 cluster ordered dither + + 8 monochrome cluster ordered dither + + 9 user-defined dither (not supported) + + 10 monochrome user-defined dither ns. + + +The PaintJet (non-XL) has no additional properties. + + + + +Gamma correction +~~~~~~~~~~~~~~~~~~~~~ + +One consequence of using Floyd-Steinberg dithering rather than Ghostscript's default clustered ordered dither is that it is much more obvious that the ink dots are rather larger on the page than their nominal 1/180-inch or 1/300-inch size (clustering the dots tends to minimise this effect). Thus it is often the case that the printed result is rather too dark. A simple empirical correction for this may be achieved by preceding the actual PostScript file to be printed by a short file which effectively sets the gamma for the device, such as: + + +.. code-block:: bash + + gs ... gamma.ps colorpic.ps -c quit + +where ``gamma.ps`` is: + +.. code-block:: postscript + + %! + /.fixtransfer { + currentcolortransfer 4 { + mark exch + dup type dup /arraytype eq exch /packedarraytype eq or + 1 index xcheck and { /exec load } if + 0.333 /exp load + ] cvx 4 1 roll + } repeat setcolortransfer + } bind odef + .fixtransfer + /setpagedevice { setpagedevice .fixtransfer } bind odef + + +This does the gamma correction after whatever correction the device might be doing already. To do the correction before the current correction: + +.. code-block:: postscript + + %! + /.fixtransfer { + currentcolortransfer 4 { + mark 0.333 /exp load 4 -1 roll + dup type dup /arraytype eq exch /packedarraytype eq or + 1 index xcheck and { /exec load } if + ] cvx 4 1 roll + } repeat setcolortransfer + } bind odef + .fixtransfer + /setpagedevice { setpagedevice .fixtransfer } bind odef + + +This example sets the gamma for R, G, and B to 3, which seems to work reasonably well in practice. + + + +HP's resolution-enhanced mode for Inkjet printers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This feature is available on HP's more recent inkjet printers, including the DeskJet 520 (mono), 540 (mono or colour) and 560C (mono and colour). The colour and monochrome drivers for the HP DeskJet 550c are (probably) the best you will get for use with Ghostscript, for the following reasons. + +These printers do not offer true 600×300dpi resolution. Those that print in colour are strictly 300×300dpi in colour mode, while in mono mode there is a pseudo 600×300dpi mode with the restriction that you can't print two adjacent dots. In effect what you have is 600dpi dot positioning, but on average you don't get more dots per line. This provides the possibility, for instance, to have sharper character outlines, because you can place dots on the edges nearer to their ideal positions. This is why it is worth doing. + +However, HP will not support user-level programming of this resolution-enhanced mode, one reason being that (I understand) all the dot spacing has to be done by the driver, and if you get it wrong, you can actually damage the print head. + +To summarise, you may lose a smidgin of (potential) text clarity using the 550c drivers (:title:`cdj550`, :title:`cdjcolor`, :title:`cdjmono` etc.), but other than that, they are the ones for the job. + + + +General tips +~~~~~~~~~~~~~~~~~~~~~ + +For all the printers above, the choice of paper is critically important to the final results. The printer manuals suggest type of paper, but in general, smoother, less fibrous types give better results. In particular, the special ink-jet paper can make a big difference: colours are brighter, but most importantly, there is almost no colour bleed, even with adjacent areas of very heavy inking. Similarly the special coated transparencies also work well (and ordinary transparencies do not work at all!). + +The Unix procedure :ref:`unix-lpr.sh<Unix-lpr.htm>` provides one example of setting up a multi-option colour PostScript lpr queue on Unix systems, and includes the ability to choose a range of different colour options and printer accounting and error logging. + +Caveat emptor! It is not always easy for me to test all of these drivers, as the only colour printer I have here is the DeskJet 500C. I rely on others to test drivers for the additional machines and report their findings back to me. + + + +Canon BJC-8200 printer +----------------------------- + +This section was contributed by the author of the :title:`uniprint` configuration files for the Canon BJC-8200, `Stephan C. Buchert`_. These files also handle the Japanese Canon F850 printer. + + +.. warning:: + + Usage of this program is neither supported nor endorsed by the Canon corporation. Please see the Ghostscript license regarding warranty. + + +Introduction +~~~~~~~~~~~~~~ + +The Canon Bubble Jet printer BJC-8200 is designed for printing digital photos and halftone images. Software drivers for Windows 95-2000 and Mac are usually included and can be downloaded from the Canon web sites for the US market. If these drivers cannot be used for some reason, then at present Ghostscript is probably the alternative giving the best results. + +The BJC-8200 has features not found among the specs of earlier bubble jet models (except the even more advanced BJC-8500) and is advertised to offer: + +#. Microfine droplet technology. +#. Support for printing on a new type of paper, Photo Paper Pro. +#. A printhead capable of printing up to 1200 DpI. +#. Individual ink tanks for 6 colors. +#. An internal status monitor reporting low ink back to a driver. +#. An optional color scanner cartridge for up to 600 DpI resolution. + +Access to features 5 and 6 requires use of the original Canon drivers for the foreseeable future. This README is about getting the printer features 1-3 working with Ghostscript. No (re)compilation of Ghostscript is normally required. + +Ghostscript comes with a relatively highly configurable driver, called uniprint_, for printers which understand raster images in various propriety formats. Most options for this driver are usually organized into files having the suffix ``.upp``. Ghostscript versions >= 5.10 (or even earlier) include such :title:`uniprint` control files for the Canon BJC-610. They work also well for some other Canon Bubble Jet models, for example for my BJC-35vII. But when using them for a BJC-8200 the result is unsatisfactory. + +The :title:`uniprint` control files for the BJC-8200 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After some experimenting with the options for :title:`uniprint` I have obtained quite satisfactory prints with :ref:`my printer<myPrinter>`. This distribution includes six new :title:`uniprint` control files: + +- ``bj8pp12f.upp`` +- ``bj8hg12f.upp`` +- ``bj8gc12f.upp`` +- ``bj8oh06n.upp`` +- ``bj8ts06n.upp`` +- ``bj8pa06n.upp`` + +They are included in Ghostscript ``>=6.21``. For older versions you can put them anywhere in the Ghostscript search path (type ``gs -h`` to see the path), but should perhaps add the files to the directory with the other ``*.upp`` files. This is ``/usr/share/ghostscript/gs6.01/lib`` in my RedHat 6.1 Linux box with Aladdin Ghostscript 6.01. + +Here is an explanation of my file name convention: the prefix "bj8" should perhaps be used for the Canon BJC-8200 and compatible (like the Japanese F850 and perhaps the non-Japanese BJC-8500) models. The next two letters indicate the print media: + +- **pp** - "Photo Paper Pro". +- **hg** - "High Gloss Photo Film". +- **gc** - "Glossy Photo Cards". +- **oh** - "OHP transparencies". +- **ts** - "T-shirt transfer". +- **pa** - "Plain Paper". + + +The numbers at positions 6 and 7 indicate the resolution + +- **12** - 1200x1200 DpIxDpI. +- **06** - 600x600 DpIxDpI. + +The last letter stands for a quality factor that effects also the print speed (presumably related to the number of passes that the printhead makes). + +- **f** - highest quality. +- **n** - normal quality. + +Printing a postcard size (~10x15 cm^2) image at 1200x1200 DpI^2 takes about 3 minutes. The output of Ghostscript is then typically 4-5 MByte. The bootleneck seems to be the transfer of the raster image in run-length encoded Canon format to the printer (via the parallel port on my system) or the printer's speed, not Ghostscript or the :title:`uniprint` renderer. + + +Further Optimization for the Canon BJC-8200 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +So far I have only experimented with the printer initialization code at the beginning of each page (``-dupBeginPageCommand``) and the resolution (``-r``). Other options, particularly the transfer arrays (``-dupBlackTransfer``, ``-dupCyanTransfer``, ``-dupMagentaTransfer``, ``-dupYellowTransfer``) and the margins (``-dupMargins``) were simply copied from the files for the BJC-610, but they may need to be changed for optimized performance. + +Here is information useful for changing or adding :title:`uniprint` control files for the BJC-8200: + +In ``-dupBeginPageCommand=...`` use the line: + +.. code-block:: postscript + + 1b28 64 0400 04b0 04b0 + + +for 1200x1200 resolution, and: + +.. code-block:: postscript + +1b28 64 0400 0258 0258 + +for 600x600. The ``-r`` option in the control file must of course match this line. Other resolutions might work as well, but I didn't try. + + +Crucial are the numbers in the lines like: + + +.. code-block:: postscript + + 1b28 63 0300 3005 04 + ^ ^ + Plain Paper 0 4 Highest quality + OHP transparency 2 . + T-shirt transfer 3 . + Glossy Photo Film 5 . + High Gloss Paper 6 0 Lowest quality + Photo Paper Pro 9 + + +Outlook +~~~~~~~~~~~~ + +Presently :title:`uniprint` can use the black (K), cyan (C), magenta (M), and yellow (Y) colors in the BJC-8200. The unused colors are photo (or light) cyan (c) and magenta (m). Also the Canon driver seems to use only CMYK, for example when printing on Photo Paper Pro in "Camera" or "SuperPhoto" mode. These modes supposedly produce prints of the best quality that the Canon driver can offer. Other modes of Canon driver do use up to all six color cartridges (CMYKcm). Therefore expanding :title:`uniprint`'s capabilities for six colors would be interesting, but it may not increase the output quality of 6-color printers such as the BJC-8200 drastically. + +More control files for :title:`uniprint` could be added in order to offer more versatility for controlling the BJC-8200 within a Ghostscript installation. The number of possible combinations for media type, resolution and print quality factor is very large, many combinations would not make much sense, many might be used here and there, but relatively rarely. The user would have to remember a name for each combination that is used. + +A better way would be to let the user patch optionally a user owned or system wide :title:`uniprint` control file before each print via some print tool. This is similar to the approach taken by Canon with their driver for Windows. Similarly a :title:`uniprint` tool could also incorporate other functions such as printing test and demo pages and the low ink warning once the protocol for this is known. Clearly it would be difficult to code such a :title:`uniprint` tool for all the platforms where Ghostscript is running. + + +Usage on RedHat Linux +~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to install a BJC-8200 printer on a RedHat Linux system with RedHat's printtool, you need also to insert with a text editor the contents of the file ``bj8.rpd`` into the RedHat printer database ``/usr/lib/rhs/rhs-printfilters/printerdb``. Insert it most appropriately after the section: + + +.. code-block:: + + StartEntry: U_CanonBJC610 + . + . + . + EndEntry + + < --- insert here "bj8.rpd" from this distribution: + < --- StartEntry: U_CanonBJC8200 + . + . + . + +.. _myPrinter: + +.. note:: + + Actually I have a F850, not a BJC-8200. That model is sold for the Japanese market only. The specs and also the external look are the same as those of the BJC-8200 models for the American and European markets. I expect that the raster image mode which is used exclusively by Ghostscript is entirely compatible for both models. + + + + +Other Canon BubbleJet (BJC) printers +--------------------------------------- + +This section was contributed by the author of the drivers, Yves Arrouye. The drivers handle Canon BJC-600, BJC-4xxx, BJC-70, Stylewriter 2x00, and BJC-800 printers. + +History +~~~~~~~~~~ + +The BJC-600 driver was written in the first place by Yoshio Kuniyoshi and later modified by Yves Arrouye. We tried to make it evolve synchronously, though Yoshio cannot be reached since a long time ago. The drivers are based on code for the HP printers by George Cameron (in fact, they are in the same file!), so he's the first person to thank. + +The 2.00 version of the drivers was a complete rewrite of the driver (arguments, optimization, colour handling, in short: everything!) by Yves Arrouye. That release was also the first one to be able to use the full width of an A3 paper size. PostScript Printer Description (PPD) files for the drivers were released with version 2.15. They are incomplete, but they can be used to drive the printers' main features. + +Configuring and building the BJC drivers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Modify values in ``gdevbjc.h``. + +Configure the drivers by modifying the default values in the file ``gdevbjc.h`` or on the compilation line. If you don't do that, the drivers use reasonable defaults that make them work "as expected". All default values shown here are defined in that file. + + +CMYK-to-RGB color conversion +"""""""""""""""""""""""""""""""""" + +By default, the drivers use the same algorithm as Ghostscript to convert CMYK colors to RGB. If you prefer to use Adobe formulas, define ``USE_ADOBE_CMYK_RGB`` when compiling. (See the top of the file ``gdevcdj.c`` to see the difference between the two.) + +Vertical centering of the printable area +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The drivers center the imageable area horizontally but not vertically, so that what can be printed does use the most of the output media. If you define ``BJC_DEFAULT_CENTEREDAREA`` when compiling, then the top and bottom margins will be the same, resulting in a (smaller) vertically centered imageable area also. + +Page margins +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +If you define ``USE_RECOMMENDED_MARGINS``, then the top and bottom margins will be the same (that is, ``BJC_DEFAULT_CENTEREDAREA`` will be defined for you) and the margins will be the 12.4mm recommended by Canon. Since margins are complicated (because one must rely on the mechanical precision of the printer), the drivers do something about the bottom margin: by default the bottom margin is 9.54mm for the BJC-600 driver and 7mm for the BJC-800. If you define ``USE_TIGHT_MARGINS``, then the bottom margin is 7mm for both drivers (but I never managed to get my own BJC-600 to print a line on this low bound, hence the larger default). Regardless of the presence of this definition, ``USE_FIXED_MARGINS`` will not allow the BJC-800 to use the lower 7mm bottom margin, so if you have a problem with the bottom margin on a BJC-800, just define that (without defining ``USE_TIGHT_MARGINS``, of course). + +A quick way to be sure the margins you selected is to print a file whose contents are: + +.. code-block:: + + %! + clippath stroke showpage + +If the margins are okay, you will get a rectangle visibly surrounding the printable area. If they're not correct, one or more of the sides will be either incomplete or completely unprinted. + + +Makefile and compilation +"""""""""""""""""""""""""""""" + +Make sure the :title:`bjc600` or :title:`bjc800` devices are in :ref:`DEVICE_DEVS in the makefile<Selecting features and devices>`; that is, look in the ``makefile`` for your platform and add them if necessary -- they may already be there. As of Ghostscript 5.10, for instance, one ``makefile`` has: + +.. code-block:: bash + + DEVICE_DEVS6=bj10e.dev bj200.dev bjc600.dev bjc800.dev + + +Use of the drivers +~~~~~~~~~~~~~~~~~~~~~~ + +There are two drivers here. The :title:`bjc600` one supports the BJC-600 and BJC-4xxx (maybe the BJC-70 as well) and the :title:`bjc800` one supports the BJC-800 series. Remarks here that apply to both drivers use the name ``bjc``. + +Supported Options and Defaults +""""""""""""""""""""""""""""""""""""""""" + +.. note :: + + "options", "properties", and "parameters" designate the same thing: device parameters that you can change. + +Giving an option an incorrect value causes an error. Unless stated otherwise, this error will be a ``rangecheckerror``. Options may be set from the Ghostscript command line (using the ``-d`` and ``-s`` switches or other predetermined switches if they have an effect on the driver) or using the PostScript Level 2 ``setpagedevice`` operator if Ghostscript has been compiled with the ``level2`` or ``level3`` device (which it should ;-)). There are no special-purpose operators such as one was able to find in Level 1 printers. + +The ``bjc`` uses 24 bits per pixel by default (unless you change the value of ``BJC_BITSPERPIXEL``), corresponding to CMYK printing. Supported modes are 1 bpp and 4 bpp (gray levels), 8 bpp, 16 bpp, 24 bpp and 32 bpp (colours). Colours are preferably stored in the CMYK model (which means, for example, that with 16 bpp there are only 16 different shades of each color) but it is possible to store them as RGB color for some depths. Some modes do Floyd-Steinberg dithering and some don't, but use the default Ghostscript halftoning (in fact, when halftoning is used, dithering takes also place but because of the low point density it is usually not efficient, and thus invisible). + +**Descriptions of printing modes by bpp and Colors** + + +.. list-table:: + :widths: 10 10 80 + :header-rows: 1 + + * - bpp + - Colors + - Mode + * - 32 + - 4 + - CMYK colour printing, Floyd-Steinberg dithering + * - 24 + - 4 + - The same. (But each primary colour is stored on 6 bits instead of 8.) + * - 24 + - 3 + - RGB colour printing, Floyd-Steinberg dithering. This mode does not use the black + + cartridge (that's why it exists, for when you don't want to use it ;-)). + + Each primary colour is stored in 8 bits as in the 32/4 mode, but black generation + + and under-color removal are done on the driver side and not by Ghostscript, + + so you have no control over it. (This mode is no longer supported in this driver.) + + * - 16 + - 4 + - CMYK colour printing, halftoned by Ghostscript. F-S dithering is still + + visible here (but the halftone patterns are visible too!). + + * - 8 + - 4 + - The same.(But each primary colour is stored in 2 bits instead of 4.) + * - 8 + - 3 + - RGB colour printing. This mode is not intended for use. What I mean is + + that it should be used only if you want to use custom halftone screens + + and the halftoning is broken using the 8/4 mode (some versions of + + Ghostscript have this problem). + * - 8 + - 1 + - Gray-level printing, Floyd-Steinberg dithering + * - 1 + - 1 + - Gray-level printing halftoned by Ghostscript + + +These modes are selected using the ``BitsPerPixel`` and ``Colors`` integer options (either from the command line or in a PostScript program using ``setpagedevice``). See below. + +A note about darkness of what is printed: Canon printers do print dark, really. And the Floyd-Steinberg dithering may eventually darken your image too. So you may need to apply gamma correction by calling Ghostscript as in: + +.. code-block:: bash + + gs -sDEVICE=bjc600 gamma.ps myfile.ps + +where ``gamma.ps`` changes the gamma correction (here to 3 for all colors); 0.45 gives me good results, but your mileage may vary. The bigger the value the lighter the output: + +.. code-block:: bash + + { 0.45 exp } dup dup currenttransfer setcolortransfer + +The drivers support printing at 90dpi, 180dpi and 360dpi. Horizontal and vertical resolutions must be the same or a limitcheck error will happen. A ``rangecheck`` will happen too if the resolution is not 90 ×2^N. If the driver is compiled with ``-DBJC_STRICT`` a ``rangecheck`` also happens if the resolution is not one of those supported. This is not the case, as we expect that there may be a 720dpi bjc some day. + + +Here are the various options supported by the ``bjc`` drivers, along with their types, supported values, effects, and usage: + +``BitsPerPixel (int)`` + Choose the depth of the page. Valid values are 1, 8, 16, 24 (the default) and 32. + Note that when this is set for the first time, the ``Colors`` property is automatically adjusted unless it is also specified. The table here shows the corresponding color models and the rendering method visible: "``GS``" for Ghostscript halftoning and "``F-S``" for Floyd-Steinberg dithering. When both are present it means that the dithering of halftones is visible. Default choices are indicated by asterisk "``*``". + + **Valid colors values for allowed BitsPerPixel values** + + + .. list-table:: + :header-rows: 1 + + * - bpp + - Colors + - Default + - Color model + - Dithering + * - 32 + - 4 + - + - CMYK + - F-S + * - 24 + - 4 + - ``*`` + - CMYK + - F-S + * - + - 3 + - + - RGB + - F-S + * - 16 + - 4 + - + - CMYK + - GS, F-S + * - 8 + - 4 + - ``*`` + - CMYK + - GS + * - + - 3 + - + - RGB + - GS + * - + - 1 + - + - K (CMYK) + - F-S + * - 1 + - 1 + - ``*`` + - K (CMYK) + - GS + + Also note that automagical change of one parameter depending on the other one does not work in a ``setpagedevice`` call. This means that if you want to change ``BitsPerPixel`` to a value whose valid ``Colors`` values do not include the actual ``Colors`` value, you must change ``Colors`` too. + + +``Colors (int)`` + Choose the number of color components from among 1, 3 and 4 (the default). This setting cannot be used in a PostScript program, only on Ghostscript's command line. See ProcessColorModel below for what to use to change the number of colors with PostScript code. + Note that setting this property does limit the choices of BitsPerPixel. As for the previous property, its first setting may induce a setting of the "other value" (BitsPerPixel here). The table here indicates valid combinations with "V", default values with asterisk "*". + + **Valid BitsPerPixel values for allowed Colors values** + + *BitsPerPixel OK values* + + .. list-table:: + :header-rows: 1 + + * - Colors + - Type + - 32 + - 24 + - 16 + - 8 + - 1 + * - 4 + - CMYK + - V + - + - V + - V + - + * - 3 + - RGB + - + - ``*`` + - + - V + - + * - 1 + - K + - + - + - + - V + - ``*`` + + + Also note that automagical change of one parameter depending on the other one does not work in a ``setpagedevice`` call. This means that if you want to change ``Colors`` to a value whose valid ``BitsPerPixel`` values don't include the actual ``BitsPerPixel`` value, you must change ``BitsPerPixel`` too. + + + +``ProcessColorModel`` *(symbol)* + A symbol taken from ``/DeviceGray``, ``/DeviceRGB`` or ``/DeviceCMYK`` which can be used to select 1, 3 or 4 colors respectively. Note that this parameter takes precedence over ``Colors``, and that both affect the same variable of the driver. (See ``Colors`` above for values combined with ``BitsPerPixel``.) + +``HWResolution`` *(floats array)* + An array of two floats giving the horizontal and vertical resolution in dots per inch from among 90, 180 and 360 (the default). Both values must be the same. On the Ghostscript command line, the resolution may be changed with the ``-r`` switch. + +``ManualFeed`` *(bool)* + Indicate that the sheets won't be fed automatically by the printer, false by default. (Not meaningful on the BJC-600, I fear.) + +``MediaType`` *(string)* + The media to print on, chosen from among "PlainPaper", "CoatedPaper", "TransparencyFilm", "Envelope", "Card" and "Other". Default is "PlainPaper". For "Envelope", "Card" or "Other" the driver puts the printer into thick mode automatically regardless of the actual media weight. + +``MediaWeight`` *(int or null)* + The weight of the media in grams per square meter. Null (the default) indicates that the weight is of no importance. If the specified media weight is greater than 105 (that is, the value of the compilation default ``BJC???_MEDIAWEIGHT_THICKLIMIT``) then the printer will be set to use thick paper. + +``PrintQuality`` *(string)* + The quality of printing. + + .. list-table:: + :header-rows: 1 + + * - Value + - bjc600 + - bjc800 + - Comments + * - Low + - + - X + - Has the effect of making only two printing passes instead of four, + + so should be twice the speed; known as "CN" (Color Normal) mode + + * - Draft + - X + - X + - Unlights the "HQ" light on a BJC-600 + * - Normal + - X + - X + - Default for both drivers; lights the "HQ" light on a BJC-600 + * - High + - X + - X + - Means 200% black and 100% C + + +``DitheringType`` *(string)* + Dithering algorithm from between "Floyd-Steinberg" and "None". "None" is the default for 1/1 print mode, "Floyd-Steinberg" for other modes. At the moment this parameter is read-only, though no error is generated if one tries to change it. This parameter is not of much value at the moment and is here mainly to reserve the name for future addition of dithering algorithms. + +``PrintColors`` *(int)* + Mask for printing color. If 0, use black for any color; otherwise the value must be the sum of any of 1 (cyan), 2 (magenta), 4 (yellow) and 8 (black), indicating which colors will be used for printing. When printing colour, only colours specified will be printed (this means that some planes will be missing if a color's value above is omitted). When printing grays, black is used if it is present in the PrintColors; otherwise, the image is printed by superimposing each requested color. + +``MonochromePrint`` *(bool)* + For :title:`bjc600` only, false by default. Substitute black for Cyan, Magenta and Yellow when printing -- useful, for example, to get some monochrome output of a dithered printing This is a hardware mechanism as opposed to the previous software one. I think that using this or setting ``PrintColors`` to 0 will give the same results. + + +.. note:: + + The ``MediaType`` and ``ThickMedia`` options will be replaced by the use of the device ``InputAttributes`` and ``OutputAttributes`` as soon as possible. Please note too that the print mode may be reset at the start of printing, not at the end. This is the expected behaviour. If you need to reset the printer to its default state, simply print a file that does just a ``showpage``. + + +Device information +""""""""""""""""""""""" + +Here is other information published by the driver that you will find in the ``deviceinfo`` dictionary. + +``OutputFaceUp`` *(bool)* + This has the boolean value true, indicating that the sheets are stacked face up. + +``Version`` *(float)* + In the form ``M.mmpp``, where ``M`` is the major version, ``mm`` the bjc driver's minor version, and ``pp`` the specific driver minor version (that is, ``M.mm`` will always be the same for the :title:`bjc600` and :title:`bjc800` drivers). + +``VersionString`` *(string)* + A string showing the driver version and other indications. At the moment, things like "a" or "b" may follow the version to indicate alpha or beta versions. The date of the last change to this version is given in the form MM/DD/YY (no, it won't adapt to your locale). + + +Hardware margins +""""""""""""""""""""""" + +The BJC printers have top and bottom hardware margins of 3mm and 7.1mm respectively (Canon says 7mm, but this is unusable because of the rounding of paper sizes to PostScript points). The left margin is 3.4mm for A4 and smaller paper sizes, 6.4mm for U.S. paper sizes, envelopes and cards. It is 4.0mm for A3 paper on the BJC-800. + +The maximum printing width of a BJC-600 printer is 203mm. The maximum printing width of a BJC-800 printer is 289mm on A3 paper, 203mm on U.S. letter and ISO A4 paper. + +PostScript printer description (PPD) files +"""""""""""""""""""""""""""""""""""""""""""""" + +The files ``CBJC600.PPD`` and ``CBJC800.PPD`` (whose long names are, respectively, ``Canon_BubbleJetColor_600.ppd`` and ``Canon_BubbleJetColor_800.ppd``) are PPD files to drive the features of the :title:`bjc600` and :title:`bjc800` drivers. They can be used, for example, on NextStep systems (presumably on OpenStep systems too) and on Unix systems with Adobe's TranScript and ``pslpr`` (not tested). The files are not complete at the moment. Please note that NextStep's printing interface does not correctly enforce constraints specified in these files (in ``UIConstraints`` descriptions): you must force yourself to use valid combinations of options. + +Customizing the PPD files +"""""""""""""""""""""""""""""""""""""""""""""" + +By default the PPD files are set for U.S. letter size paper, and they use a normalized transfer function. If you choose to use A4 printing by default, you must replace "Letter" with "A4" in these (noncontiguous) lines: + +.. code-block:: + + [...] + *DefaultPageSize: Letter + [...] + *DefaultRegion: Letter + [...] + *DefaultImageableArea: Letter + [...] + +Some versions of Ghostscript have problems with normalized colors, which makes them add magenta in gray levels. If you experience this problem, in the PPD file replace the line: + +.. code-block:: + + *DefaultTransfer: Normalized + +with the alternate line: + +.. code-block:: + + *DefaultTransfer: Null + +The "thick media" option is implemented by choosing a value of 120 or 80 (for thick and thin media respectively) for the ``MediaWeight`` feature of the drivers. If you ever change the threshold for thick media in the driver code, you may need to change the values in the PPD files too. + +All customization should be done using the "``*Include:``" feature of PPD files so that your local changes will be retained if you update the PPD files. + + + +How to report problems +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Yves Arrouye no longer maintains this driver, and will not answer questions about it. If you are posting a question about it in a public form, please be as descriptive as possible, and please send information that can be used to reproduce the problem. Don't forget to say which driver you use, and in what version. Version information can be found in the source code of the driver or by issuing the following command in a shell: + +.. code-block:: bash + + echo "currentpagedevice /VersionString get ==" | gs -q -sDEVICE=bjc600 - + + +Acknowledgements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I am particularly grateful to `Yoshio Kuniyoshi`_ without whom I'd never make these drivers, and also to L. Peter Deutsch, who answered all my (often silly) questions about Ghostscript's driver interface. + +Thanks also to the people who volunteered to beta-test the v2.x BJC drivers: `David Gaudine`_, `Robert M. Kenney`_, `James McPherson`_ and `Ian Thurlbeck`_ (listed alphabetically) were particularly helpful by discovering bugs and helping find out exact paper margins on printers I don't have access to. + +And many thanks to `Klaus-Gunther Hess`_ for looking at the dithering code and devising a good CMYK dithering algorithm for the Epson Stylus Color, which I then adapted to the code of these drivers. + + + + +Epson Stylus color printer (see also :title:`uniprint`) +---------------------------------------------------------- + +This section was contributed by `Gunther Hess`_, who also wrote uniprint_, a later set of drivers. You should probably see the section on uniprint_ for whether it might be better for your uses than this driver. + +Usage +~~~~~~~~~ + +This driver is selected with ``-sDEVICE=stcolor``, producing output for an Epson Stylus Color at 360dpi resolution by default. But it can do much more with this printer, and with significantly better quality, than with the default mode; and it can also produce code for monochrome versions of the printer. This can be achieved via either command-line options or Ghostscript input. For convenience a PostScript file is supplied for use as an initial input file. Try the following command: + +.. code-block:: bash + + gs -sDEVICE=stcolor -r{Xdpi}x{Ydpi} stcolor.ps {YourFile.ps} + + +where {Xdpi} is one of 180, 360, or 720 and {Ydpi} is one of 90, 180, 360, or 720. The result should be significantly better. You may use stcolor.ps with other devices too, but I do not recommend this, since it does nothing then. stcolor.ps should be available with binary distributions and should reside in the same directory as other Ghostscript initialization files or in the same directory as the files to be printed. Thus if Ghostscript is part of your printer-spooler, you can insert: + +.. code-block:: postscript + + (stcolor.ps) findlibfile { pop run } if pop + +in files you want to use the improved algorithms. You may want to adapt ``stcolor.ps`` file to your specific needs. The methods and options for this are described here, but this description is restricted to Ghostscript options, while their manipulation at the PostScript level is documented in the material on the relationship of Ghostscript and PostScript and in ``stcolor.ps``. + + +Options +~~~~~~~~~ + +Now to explain the options (as written on my UNIX system). The order is somehow related to their use during the printing process: + +``-dUnidirectional`` + Force unidirectional printing, recommended for transparencies + +``-dMicroweave`` + Enable the printer's "microweave" feature; see "What is weaving?" below. + +``-dnoWeave`` + Disable any Weaving (overrides ``-dMicroweave``) + +``-dSoftweave`` + Enable the driver's internal weaving. Note that Softweave works only with the original Stylus Color and the PRO-Series. + +``-sDithering=`` *{name}* + Select another dithering algorithm (name) from among: + + .. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - Dithering name + - Comments + * - ``gscmyk`` + - fast color output, CMYK process color model (default) + * - ``gsmono`` + - fast monochrome output + * - ``gsrgb`` + - fast color output, RGB process color model + * - ``fsmono`` + - Floyd-Steinberg, monochrome + * - ``fsrgb`` + - Floyd-Steinberg, RGB process color model (almost identical to + + the ``cdj550/bjc`` algorithm) + * - ``fsx4`` + - Floyd-Steinberg, CMYK process color model (shares code with ``fsmono`` and + + ``fsrgb``, but is algorithmically really bad) + * - ``fscmyk`` + - Floyd-Steinberg, CMYK process color model and proper modifications for CMYK + * - ``hscmyk`` + - modified Floyd-Steinberg with CMYK model ("hs" stands for "hess" not + + for "high speed", but the major difference from ``fscmyk`` is speed) + * - ``fs2`` + - algorithm by Steven Singer (RGB) should be identical to ``escp2cfs2``. + + +``-dBitsPerPixel={1...32}`` + number of bits used for pixel storage; the larger the value, the better the quality -- at least in theory. In ``fsrgb`` one can gain some speed by restricting to 24 bits rather than the default 30. + +``-dFlag0`` + causes some algorithms to select a uniform initialisation rather than a set of random values. May yield a sharper image impression at the cost of dithering artifacts. (Applies to ``hscmyk`` and all ``fs`` modes, except for ``fs2``, which always uses a constant initialization.) + +``-dFlag1 ... -dFlag4`` + Available for future algorithms. + +``-dColorAdjustMatrix='{three, nine, or sixteen floating-point values}'`` + This is a matrix to adjust the colors. Values should be between -1.0 and 1.0, and the number of values depends on the color model the selected algorithm uses. In RGB and CMYK modes a matrix with 1.0 on the diagonal produces no transformation. This feature is really required, but I could not identify a similar feature at the language level, so I implemented it, but I don't know reasonable values yet. + +``-dCtransfer='{float float ...}'`` or ``-dMtransfer=..., -dY..., -dK...`` or ``-dRtransfer='{float float ...}'`` or ``-dG..., -dB...`` or ``-dKtransfer='{float float ...}'`` + Which you use depends on the algorithm, which may be either either CMYK, RGB or monochrome. The values are arrays of floats in the range from 0 to 1.0, representing the visible color intensity for the device. One may achieve similar effects with ``setcolortransfer`` at the language level, but this takes more time and the underlying code for the driver-specific parameters is still required. The size of the arrays is arbitrary and the defaults are "{0.0 1.0}", which is a linear characteristic. Most of the code in stcolor.ps are better transfer arrays. + + +``-dKcoding='{float...}'`` , ``-dC..., -dM...`` etc. + Arrays between 0.0 and 1.0, controlling the internal coding of the color values. Clever use of these arrays may yield further enhancements, but I have no experience yet. (To be discontinued with version 2.x.) + +``-sModel=st800`` + Causes output to be suitable for the monochrome Stylus 800 (no weaving, no color). + +``-sOutputCode=`` *{name}* + Can be either "``plain``", "``runlength``" or "``deltarow``" and changes the ESC/P2 coding technique used by the driver. The default is to use runlength encoding. "``plain``" selects uncompressed encoding and generates enormous amounts of data. + +``-descp_Band=`` *1/8/15/24* + Number of nozzles of scanlines used in printing, Useful only with -dnoWeave. Larger Values yield smaller code, but this doesn't increase the printing speed. + +``-descp_Width=`` *N* + Number of pixels Printed in each scan Line. (Useful only when tuning margins; see below) + +``-descp_Height=`` *pixels* + Length of the entire page in pixels. (Parameter of "``ESC(C``" in default initialization.) + +``-descp_Top=`` *scan lines* + Top margin in scan lines. (First parameter of "``ESC(c``" in default initialization.) + +``-descp_Bottom=`` *scan lines* + Bottom margin in scan lines. (Second parameter of "``ESC(c``" in default initialization.) + +``-sescp_Init=`` *"string"* + Override for the initialization sequence. (Must set graphics mode 1 and units.) + +``-sescp_Release=`` *"string"* + Overrides the release sequence, "``ESC @ FF``" by default. + +ESC/P2 allows any resolutions to be valid in theory, but only ``-r360x360`` (the default) and ``-r720x720`` (not on STC-IIs ? and :title:`st800`) are known to work with most printers. + + +**Valid option combinations – Stylus I & Pro-Series only** + +.. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Resolution + - escp_Band + - Weave usable + - escp_Band & number of passes + * - 180x90 + - 15 + - noWeave + - + * - 180x180 + - 1, 8, 24 + - noWeave, Microweave + - 15/2 SoftWeave + * - 180x360 + - + - + - 15/4 SoftWeave + * - 180x720 + - + - + - 15/8 SoftWeave + * - 360x90 + - 15 + - noWeave + - + * - 360x180 + - 1, 8, 24 + - noWeave, Microweave + - 15/2 SoftWeave + * - 360x360 + - 1, 8, 24 + - noWeave, Microweave + - 15/4 SoftWeave + * - 360x720 + - + - + - 15/8 SoftWeave + * - 720x90 + - 15 + - noWeave + - + * - 720x180 + - + - + - 15/2 SoftWeave + * - 720x360 + - + - + - 15/4 SoftWeave + * - 720x720 1 noWeave, Microweave + - 1 + - noWeave, Microweave + - 15/8 SoftWeave + + +.. warning :: + + Beware: there are only few validity checks for parameters. A good example is ``escp_Band``: if you set this, the driver uses your value even if the value is not supported by the printer. You asked for it and you got it! + + + +Application note and FAQ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Quite a bunch of parameters. Hopefully you never need any of them, besides feeding stcolor.ps to Ghostscript in front of your input. + +After answering some questions over fifty times I prepared a FAQ. Here is version 1.3 of the FAQ, as of stcolor version 1.20 (for Ghostscript 3.50). + +Support for A3 paper +""""""""""""""""""""""""""" + +Yes, this driver supports the A3-size printer: merely set the required ``pagesize`` and margins. A simple way to do this is to specify the command-line switch ``-sPAPERSIZE=a3`` or include the procedure call ``a3`` in the PostScript prolog section. To optimize the printable area or set the proper margins, see the next paragraph. + +Margins, PageSize +""""""""""""""""""""" + +I refuse to add code to :title:`stcolor` that tries to guess the proper margins or page size, because I found that such guessing is usually wrong and needs correction in either the source or the parameters. You can modify ``stcolor.ps`` to do that, however. After the line: + +.. code-block:: postscript + + mark % prepare stack for "putdeviceprops" + +insert these lines, which define page size and margins in points: + +.. code-block:: postscript + + /.HWMargins [9.0 39.96 12.6 9.0] % Left, bottom, right, top (1/72") + /PageSize [597.6 842.4] % Paper, including margins (1/72") + /Margins [ % neg. Offset to Left/Top in Pixels + 4 index 0 get STCold /HWResolution get 0 get mul 72 div neg + 5 index 3 get STCold /HWResolution get 1 get mul 72 div neg + ] + + +Feel free to change the values of ``.HWMargins`` and ``PageSize`` to match your needs; the values given are the defaults when the driver is compiled with "``-DA4``". This option or its omission may cause trouble: the Stylus Color can print up to exactly 8 inches (2880 pixels) at 360dpi. The remaining paper is the margin, where the left margin varies only slightly with the paper size, while the right margin is significantly increased for wider paper, such as U.S. letter size. + + +.. note :: + + If you are using an ISO paper size with a version of stcolor after 1.20 and compiled without "``-DA4``", then the default margin is too large, and you need to add the proper "``.HWMargins``" to the command line or to ``stcolor.ps``. + + +Stylus Color II / IIs and 1500 +"""""""""""""""""""""""""""""""""""""""""" + +First the good news: the driver can print on the Stylus Color II. Now the bad news: + +- According to Epson support the driver "abuses" the color capabilities. (See "Future Plans" for details). +- You need some parameters on the command line (or in ``stcolor.ps``). +- I doubted that it would be usable with the Stylus Color IIs, but it is usable and suffers from mixing problems! + +To make things work, you MUST disable the driver's internal weaving (Softweave), in one of these two ways: + + +.. code-block:: bash + + gs -dMicroweave ... + gs -dnoWeave -descp_Band=1 ... + + +Version 1.90, current as of Ghostscript 5.10, fixes this bug by new default behaviour. I experienced significantly increased printing speed with the second variant on the old Stylus Color, when printing mostly monochrome data. + + +Recommendations +~~~~~~~~~~~~~~~~~~~~~ + +The next section is a contribution from `Jason Patterson`_ who evaluated a previous version (1.17). Ghostscript was invoked as follows: + +.. code-block:: bash + + gs -sDEVICE=stcolor -r720x720 -sDithering=... -sOutputFile=escp.out stcolor.ps whatsoever.ps + + +where "``...``" is the name of the desired algorithm. ``stcolor.ps`` was omitted for the gs-algorithms (``gsmono``, ``gsrgb`` and ``gscmyk``), for which it is useless and would not allow the selection of "``gscmyk``". + +Color dithering experiments with gdevstc 1.21 +"""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Here are data about the EPSON Stylus Color driver's different dithering methods, based on a little experiment using four good quality scanned images of quite varied nature, to begin with, a summary of the results of the four experiments. Sanity note: the results here are from only four images and a total of 24 printouts (eight on 720dpi paper, sixteen on plain paper). Your results will almost certainly vary, and your standards might not be the same as mine, so use these results only as a guide, not as a formal evaluation. + + +**Quality of output by method** + + +.. list-table:: + :widths: 15 85 + :header-rows: 0 + + * - ``gsmono`` + - Pretty much what you'd expect from a mono ordered pattern. Looks like what a lot of mono laser printers produce. + * - ``fsmono`` + - Excellent for monochrome. + * - ``gscmyk`` + - Not very good, but expected from an ordered pattern. + * - ``gsrgb`` + - A little better than gscmyk. More consistent looking. + * - ``fs2`` + - Good, but not quite as good as fsrgb. Gets the brightness wrong: too light at 720dpi, too dark at 360dpi. + * - ``fsrgb`` + - Very good, but a little too dark and has a slight blue tint. + * - ``hscmyk`` + - Excellent. Slightly better than fsrgb and fs2. Better than fscmyk on some images, almost the same on most. + * - ``fscmyk`` + - Best. Very, very slightly better than hscmyk. On some images nearly as good as the EPSON demos done with the MS Windows driver. + + + +**Overall visual quality (1-10), best to worst** + + +.. list-table:: + :widths: 15 85 + :header-rows: 1 + + * - + - 0 1 2 3 4 5 6 7 8 9 10 + * - Monochrome + - + * - ``fsmono`` + - ``******************`` + * - ``gsmono`` + - ``**********`` + * - Colour + - + * - ``fscmyk`` + - ``*******************`` + * - ``hscmyk`` + - ``*******************`` + * - ``fsrgb`` + - ``******************`` + * - ``fs2`` + - ``*****************`` + * - ``gsrgb`` + - ``**********`` + * - ``gscmyk`` + - ``*********`` + + + +Color transformation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the initial version of the driver distributed with Ghostscript 3.33, the parameter ``SpotSize`` was the only way to manipulate the colors at the driver level. According to the parameters enumerated above, this has changed significantly with version 1.16 and above as a result an ongoing discussion about dithering algorithms and "false color" on the Epson Stylus Color. This initiated the transformation of the :title:`stcolor` driver into a framework for different dithering algorithms, providing a generalized interface to the internal Ghostscript color models and the other data structures related to Ghostscript drivers. + +The main thing such a framework should be able to do is to deliver the values the dithering algorithm needs; and since this directly influences the optical image impression, this transformation should be adjustable without the need for recompilation and relinking. + + +Due to the limitations on raster storage, information is lost in the first transformation step, except for the 16-bit monochrome mode. So any color adjustment should take place before this step and this is where the optional ``ColorAdjustMatrix`` works. + +The first transformation step, called "coding", is controlled by the ``?coding`` arrays. The decoding process expands the range of values expontentially to a larger range than that provided by the initial Ghostscript color model, and is therefore a reasonable place to make device- or algorithm-specific adjustments. This is where the ``?transfer`` arrays are used. Array access might be not the fastest method, but its generality is superior, so this step is always based upon internally algorithm-specific array access. If 8 bits are stored per color component and if the algorithm uses bytes too, the second transformation is included within the first, which saves significant computation time when printing the data. + + +ColorAdjustMatrix +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The driver supports different values for ``ProcessColorModel``, which raises the need for different color adjustments. Here "CAM" stands for "ColorAdjustMatrix". + +.. code-block:: + + DeviceGray (three floats) + if ((r == g) && (g == b)) + K' = 1.0 - R; + else + K' = 1.0 - CAM[0] * R + CAM[1] * G + CAM[2] * B; + + +According to the documentation on drivers, the latter (the "else" clause) should never happen. + + +.. code-block:: + + DeviceRGB (nine floats) + if((r == g) && (g == b)) + R' = B' = G' = R; + else + R' = CAM[0]*R + CAM[1]*G + CAM[2]*B; + G' = CAM[3]*R + CAM[4]*G + CAM[5]*B; + B' = CAM[6]*R + CAM[7]*G + CAM[8]*B; + +The printer always uses four inks, so a special treatment of black is provided. Algorithms may take special action if R, G, and B are all equal. + + +.. code-block:: + + DeviceCMYK (sixteen floats) + if((c == m) && (m == y)) + K' = max(C,K); + C' = M' = Y' = 0; + else + K = min(C,M,Y); + if((K > 0) && ColorAdjustMatrix_present) { => UCR + C -= K; + M -= K; + Y -= K; + } + + C' = CAM[ 0]*C + CAM[ 1]*M + CAM[ 2]*Y + CAM[ 3]*K; + M' = CAM[ 4]*C + CAM[ 5]*M + CAM[ 6]*Y + CAM[ 7]*K; + Y' = CAM[ 8]*C + CAM[ 9]*M + CAM[10]*Y + CAM[11]*K; + K' = CAM[12]*C + CAM[13]*M + CAM[14]*Y + CAM[15]*K; + + +Again we have a special black treatment. "``max(C,K)``" was introduced because of a slight misbehaviour of Ghostscript, which delivers black under certain circumstances as (1,1,1,0). Normally, when no special black separation and undercolor removal procedures are defined at the PostScript level, either (C,M,Y,0) or (0,0,0,K) values are mapped. This would make the extended ``ColorAdjustMatrix`` quite tedious, and so during mapping, black separation is done for (C,M,Y,0) requests; and if there is a ``ColorAdjustMatrix``, undercolor removal is used too. In other words the default matrix is: + + +.. list-table:: + :header-rows: 0 + + * - 1 + - 0 + - 0 + - 1 + * - 0 + - 1 + - 0 + - 1 + * - 0 + - 0 + - 1 + - 1 + * - 0 + - 0 + - 0 + - 1 + +and it is applied to CMYK values with separated and removed black. Raising the CMY coefficients while lowering the K coefficients reduces black and intensifies color. But be careful, because even small deviations from the default cause drastic changes. + + +If no ``ColorAdjustMatrix`` is set, the matrix computations are skipped. Thus the transformation reduces to range inversion in monochrome mode and black separation in CMYK mode. + + + +RGB / CMYK coding and transfer, and ``BitsPerPixel`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These two (groups of) parameters are arrays of floating-point numbers in the range 0.0 to 1.0. They control the truncation to the desired number of bits stored in raster memory (``BitsPerPixel``) and the ink density. The "truncation" may become a nonlinear function if any of the ``?coding`` arrays is set. Assume the following Ghostscript invocation: + + +.. code-block:: bash + + gs -sDEVICE=stcolor -sDithering=fscmyk -dBitsPerPixel=16 \ + -dKcoding='{ 0.0 0.09 0.9 1.0 }' \ + -dMcoding='{ 0.0 0.09 0.9 1.0 }' \ + -dKtransfer='{ 0.0 0.09 0.9 1.0 }' \ + -dYtransfer='{ 0.0 0.09 0.9 1.0 }' + + +We may have either or both of ``?coding`` and ``?transfer``, giving four possible combinations. (These four combinations appear in the given example.) The resulting mapping appears in the following tables, where except for the internal Indices (4 components × 4 bits = 16 ``BitsPerPixel``), all values are normalized to the range 0 to 1. The actual range is 0 to 65535 for the Ghostscript color and 0 to 16777215 for the ink values delivered to the ``fscmyk`` algorithm. Sorry for the bunch of numbers following, but you may try this example in conjunction with ``stcinfo.ps``, which should give you a graphical printout of the following numbers when you issue a ``showpage`` command. + + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th></th> + <th colspan="3">Cyan</th> + <th colspan="3">Magenta</th> + </tr> + <tr> + <th>CI/15</th> + <th>gs_color_values</th> + <th>CI</th> + <th>Ink</th> + <th>gs_color_values</th> + <th>CI</th> + <th>Ink</th> + </tr> + <tr> + <td align="center">0.000</td> + <td align="center">0.000 - 0.062</td> + <td align="center">0</td> + <td align="center">0.000</td> + <td align="center">-0.123 - 0.123</td> + <td align="center">0</td> + <td align="center">0.000</td> + </tr> + <tr> + <td align="center">0.067</td> + <td align="center">0.063 - 0.125</td> + <td align="center">1</td> + <td align="center">0.067</td> + <td align="center">0.123 - 0.299</td> + <td align="center">1</td> + <td align="center">0.247</td> + </tr> + <tr> + <td align="center">0.133</td> + <td align="center">0.125 - 0.187</td> + <td align="center">2</td> + <td align="center">0.133</td> + <td align="center">0.299 - 0.365</td> + <td align="center">2</td> + <td align="center">0.351</td> + </tr> + <tr> + <td align="center">0.200</td> + <td align="center">0.188 - 0.250</td> + <td align="center">3</td> + <td align="center">0.200</td> + <td align="center">0.365 - 0.392</td> + <td align="center">3</td> + <td align="center">0.379</td> + </tr> + <tr> + <td align="center">0.267</td> + <td align="center">0.250 - 0.312</td> + <td align="center">4</td> + <td align="center">0.267</td> + <td align="center">0.392 - 0.420</td> + <td align="center">4</td> + <td align="center">0.406</td> + </tr> + <tr> + <td align="center">0.333</td> + <td align="center">0.313 - 0.375</td> + <td align="center">5</td> + <td align="center">0.333</td> + <td align="center">0.420 - 0.447</td> + <td align="center">5</td> + <td align="center">0.433</td> + </tr> + <tr> + <td align="center">0.400</td> + <td align="center">0.375 - 0.437</td> + <td align="center">6</td> + <td align="center">0.400</td> + <td align="center">0.447 - 0.475</td> + <td align="center">6</td> + <td align="center">0.461</td> + </tr> + <tr> + <td align="center">0.467</td> + <td align="center">0.438 - 0.500</td> + <td align="center">7</td> + <td align="center">0.467</td> + <td align="center">0.475 - 0.502</td> + <td align="center">7</td> + <td align="center">0.488</td> + </tr> + <tr> + <td align="center">0.533</td> + <td align="center">0.500 - 0.562</td> + <td align="center">8</td> + <td align="center">0.533</td> + <td align="center">0.502 - 0.529</td> + <td align="center">8</td> + <td align="center">0.516</td> + </tr> + <tr> + <td align="center">0.600</td> + <td align="center">0.563 - 0.625</td> + <td align="center">9</td> + <td align="center">0.600</td> + <td align="center">0.529 - 0.557</td> + <td align="center">9</td> + <td align="center">0.543</td> + </tr> + <tr> + <td align="center">0.667</td> + <td align="center">0.625 - 0.687</td> + <td align="center">10</td> + <td align="center">0.667</td> + <td align="center">0.557 - 0.584</td> + <td align="center">10</td> + <td align="center">0.571</td> + </tr> + <tr> + <td align="center">0.733</td> + <td align="center">0.688 - 0.750</td> + <td align="center">11</td> + <td align="center">0.733</td> + <td align="center">0.584 - 0.612</td> + <td align="center">11</td> + <td align="center">0.598</td> + </tr> + <tr> + <td align="center">0.800</td> + <td align="center">0.750 - 0.812</td> + <td align="center">12</td> + <td align="center">0.800</td> + <td align="center">0.612 - 0.639</td> + <td align="center">12</td> + <td align="center">0.626</td> + </tr> + <tr> + <td align="center">0.867</td> + <td align="center">0.813 - 0.875</td> + <td align="center">13</td> + <td align="center">0.867</td> + <td align="center">0.639 - 0.715</td> + <td align="center">13</td> + <td align="center">0.653</td> + </tr> + <tr> + <td align="center">0.933</td> + <td align="center">0.875 - 0.937</td> + <td align="center">14</td> + <td align="center">0.933</td> + <td align="center">0.715 - 0.889</td> + <td align="center">14</td> + <td align="center">0.778</td> + </tr> + <tr> + <td align="center">1.000</td> + <td align="center">0.938 - 1.000</td> + <td align="center">15</td> + <td align="center">1.000</td> + <td align="center">0.889 - 1.111</td> + <td align="center">15</td> + <td align="center">1.000</td> + </tr> + </table> + +| + +The difference between cyan and magenta is the presence of a coding array. The coding process must map a range of color values to each of the sixteen component indices. If no coding array is given, this is accomplished by dividing by 4096, equivalent to a right shift by 12 bits. The final ink density resides in the given interval and moves from the left to the right side from 0 to 15. For magenta there is a coding array and the ink value matches the center of the intervals. But the distribution of the mapped intervals follows the given coding array and is nonlinear in the linear color space of Ghostscript. + +Now let us take a look at the case with transfer arrays: + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th></th> + <th colspan="3">Yellow</th> + <th colspan="3">Black</th> + </tr> + <tr> + <th>CI/15</th> + <th>gs_color_values</th> + <th>CI</th> + <th>Ink</th> + <th>gs_color_values</th> + <th>CI</th> + <th>Ink</th> + </tr> + <tr> + <td align="center">0.000</td> + <td align="center">0.000 - 0.062</td> + <td align="center">0</td> + <td align="center">0.000</td> + <td align="center">-0.123 - 0.123</td> + <td align="center">0</td> + <td align="center">0.000</td> + </tr> + <tr> + <td align="center">0.067</td> + <td align="center">0.063 - 0.125</td> + <td align="center">1</td> + <td align="center">0.018</td> + <td align="center">0.123 - 0.299</td> + <td align="center">1</td> + <td align="center">0.067</td> + </tr> + <tr> + <td align="center">0.13</td> + <td align="center">0.125 - 0.187</td> + <td align="center">2</td> + <td align="center">0.036</td> + <td align="center">0.299 - 0.365</td> + <td align="center">2</td> + <td align="center">0.133</td> + </tr> + <tr> + <td align="center">0.200</td> + <td align="center">0.188 - 0.250</td> + <td align="center">3</td> + <td align="center">0.054</td> + <td align="center">0.365 - 0.392</td> + <td align="center">3</td> + <td align="center">0.200</td> + </tr> + <tr> + <td align="center">0.267</td> + <td align="center">0.250 - 0.312</td> + <td align="center">4</td> + <td align="center">0.072</td> + <td align="center">0.392 - 0.420</td> + <td align="center">4</td> + <td align="center">0.267</td> + </tr> + <tr> + <td align="center">0.333</td> + <td align="center">0.313 - 0.375</td> + <td align="center">5</td> + <td align="center">0.090</td> + <td align="center">0.420 - 0.447</td> + <td align="center">5</td> + <td align="center">0.333</td> + </tr> + <tr> + <td align="center">0.400</td> + <td align="center">0.375 - 0.437</td> + <td align="center">6</td> + <td align="center">0.252</td> + <td align="center">0.447 - 0.475</td> + <td align="center">6</td> + <td align="center">0.400</td> + </tr> + <tr> + <td align="center">0.467</td> + <td align="center">0.438 - 0.500</td> + <td align="center">7</td> + <td align="center">0.414</td> + <td align="center">0.475 - 0.502</td> + <td align="center">7</td> + <td align="center">0.467</td> + </tr> + <tr> + <td align="center">0.533</td> + <td align="center">0.500 - 0.562</td> + <td align="center">8</td> + <td align="center">0.576</td> + <td align="center">0.502 - 0.529</td> + <td align="center">8</td> + <td align="center">0.533</td> + </tr> + <tr> + <td align="center">0.600</td> + <td align="center">0.563 - 0.625</td> + <td align="center">9</td> + <td align="center">0.738</td> + <td align="center">0.529 - 0.557</td> + <td align="center">9</td> + <td align="center">0.600</td> + </tr> + <tr> + <td align="center">0.667</td> + <td align="center">0.625 - 0.687</td> + <td align="center">10</td> + <td align="center">0.900</td> + <td align="center">0.557 - 0.584</td> + <td align="center">10</td> + <td align="center">0.667</td> + </tr> + <tr> + <td align="center">0.733</td> + <td align="center">0.688 - 0.750</td> + <td align="center">11</td> + <td align="center">0.920</td> + <td align="center">0.584 - 0.612</td> + <td align="center">11</td> + <td align="center">0.733</td> + </tr> + <tr> + <td align="center">0.800</td> + <td align="center">0.750 - 0.812</td> + <td align="center">12</td> + <td align="center">0.940</td> + <td align="center">0.612 - 0.639</td> + <td align="center">12</td> + <td align="center">0.800</td> + </tr> + <tr> + <td align="center">0.867</td> + <td align="center">0.813 - 0.875</td> + <td align="center">13</td> + <td align="center">0.960</td> + <td align="center">0.639 - 0.715</td> + <td align="center">13</td> + <td align="center">0.867</td> + </tr> + <tr> + <td align="center">0.933</td> + <td align="center">0.875 - 0.937</td> + <td align="center">14</td> + <td align="center">0.980</td> + <td align="center">0.715 - 0.889</td> + <td align="center">14</td> + <td align="center">0.933</td> + </tr> + <tr> + <td align="center">1.000</td> + <td align="center">0.938 - 1.000</td> + <td align="center">15</td> + <td align="center">1.000</td> + <td align="center">0.889 - 1.111</td> + <td align="center">15</td> + <td align="center">1.000</td> + </tr> + </table> + +| + +Yellow uses a transfer array. There is no linear correspondence between the color and the ink values: this correspondence is defined through the given array. In other words, the transfer arrays define a nonlinear ink characteristic, which is exactly the same functionality that PostScript's "(color)transfer" function provides. + +While for yellow the intervals match the intervals used with cyan, for black the intervals match the magenta intervals. But watch the correspondence between the CI/15 values and the ink density for black: this is a linear distribution in the ink domain. + +Not a bad idea, I think. Consider the ``fs2`` algorithm: it uses values in the range 0 to 255. If any transfer array were alone, some of the 256 possible values would never be used and others would be used for adjacent intervals several times. Establishing an identical coding array solves this problem, so the full potential of the algorithm is used. + +Another useful feature of the coding arrays is that they are internally normalized to the range 0-1. In 720x720dpi mode the transfer arrays in ``stcolor.ps`` limit the dot density to about 50%, so these arrays end at 0.5 (and begin at 0.5 for RGB). Because of automatic normalization, these arrays can also be used as coding arrays. But of course in the ``fs2`` case mentioned above, values from 0 to 127 will never be delivered to the algorithm, while values 128-255 are delivered for adjacent intervals. + +To clarify the intended use of the three parameters (parameter groups), keep this in mind: + + +- ``ColorAdjustMatrix`` is never used when transferring gray values. This restricts it to what the name says: adjustment of colors, that is, correction for miscolored ink. Do not use it for saturation or brightness control. + +- ``?transfer`` arrays control the values delivered to the driver, which in turn controls the ink quantity. Use these arrays to control saturation and brightness. In general these arrays are identical for all inks. If they differ they provide a simpler scheme for color correction, which is not necessarily faster than the ``ColorAdjustMatrix``. + +- ``?coding`` arrays control the color value intervals mapped to the internal color indices. + + +What is weaving? +~~~~~~~~~~~~~~~~~~~~~ + +The Epson Stylus Color has a head assembly that contains two physically identifiable heads, one for black and one for cyan, magenta, and yellow (CMY). This makes four "logical" heads, one for each color component. Each of these four heads has several jets at some vertical (Y) distance from one another, so several horizontal lines can be printed of a given color during one pass of the heads. From experience I think there are fifteen jets per color, spaced at 1/90in. + +So the question arises of how to print at a Y resolution of 360dpi with 90dpi jets. Simply by division one gets 360dpi/90dpi = 4, which tells us that 4 passes of the head assembly are needed to achieve a Y resolution of 360dpi. + +Weaving is the method of how the fifteen jets are used to print adjacent horizontal rows separated here by 1/360 inch: + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="10">Print-head jets used with and without weaving</th> + </tr> + <tr> + <th></th> + <th></th> + <th colspan="4">Weaving</th> + <th colspan="4">noWeave</th> + </tr> + <tr> + <td></td> + <td>Pass</td> + <td>1</td> + <td>2</td> + <td>3</td> + <td>4</td> + <td>1</td> + <td>2</td> + <td>3</td> + <td>4</td> + </tr> + <tr> + <td colspan="10">Row</td> + </tr> + <tr> + <td align="center">0</td> + <td></td> + <td align="center">jet 0</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 0</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + </tr> + <tr> + <td align="center">1</td> + <td></td> + <td align="center">--</td> + <td align="center">jet 1</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 0</td> + <td align="center">--</td> + <td align="center">--</td> + </tr> + <tr> + <td align="center">2</td> + <td></td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 2</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 0</td> + <td align="center">--</td> + </tr> + <tr> + <td align="center">3</td> + <td></td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 3</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 0</td> + </tr> + <tr> + <td align="center">4</td> + <td></td> + <td align="center">jet 1</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 1</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + </tr> + <tr> + <td align="center">5</td> + <td></td> + <td align="center">--</td> + <td align="center">jet 2</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 1</td> + <td align="center">--</td> + <td align="center">--</td> + </tr> + <tr> + <td align="center">6</td> + <td></td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 3</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">--</td> + <td align="center">jet 1</td> + <td align="center">--</td> + </tr> + <tr> + <td colspan="10">...</td> + </tr> + </table> + + +Now let's assume that the dot diameter is different for each individual jet, but the average among the jets matches the desired resolution. With weaving, adjacent rows are printed by different jets, thus some averaging takes place. Without weaving, adjacent rows are printed by the same jet and this makes the dot diameter deviations visible as 1/90in stripes on the paper. + + +Print mode parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The parameters "``Unidirectional``", "``Microweave``", "``noWeave``", "``OutputCode``", "``Model``" and the given resolution control the data generated for the printer. + +Unidirectional +""""""""""""""""""" + +Simply toggles the unidirectional mode of the printer. Setting "``Unidirectional``" definitely slows printing speed, but may improve the quality. I use this for printing transparencies, where fast head movement could smear the ink. + +Microweave, noWeave and OutputCode=deltarow +""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The first are two booleans, which implies that four combinations are possible. Actually only three exist (if you don't count for ``deltarow``): ``Softweave``, ``Microweave``, and ``noWeave``. The first and second are functionally identical, the difference being whether the driver or the printer does the job. + +In the default ``Softweave`` mode the driver sends the data properly arranged to the printer, while in ``Microweave`` mode, it is the printer that arranges the data. But in general the host processor is much faster than the printer's processor, and thus it is faster for the host do the job. In addition to that, for 720dpi eight passes are required, and the amount of buffer space needed to buffer the data for the passes is far beyond the printer's memory. ``Softweave`` requires an odd value of "``escp_Band``"; the Stylus Color provides fifteen for that. + +"OutputCode" controls the encoding used. In the basic modes, the choice consists of "plain" and "runlength". The computation of runlength-encoded data does not take much time, less than the data tranfer to the printer; thus this is the recommended mode, and of course the default. With the Stylus Color, Epson introduced some new encoding principles, namely "tiff" and "deltarow". While the first was omitted from this driver for lack of apparent advantages, ``deltarow`` is available as an option. ``Softweave`` cannot be used with this encoding, so if ``OutputCode=deltarow`` is set, ``Microweave`` becomes the default. Maybe that the size of the ESC/P2 code becomes smaller, but I have never observed faster printing speed. Things tend to become slower with ``deltarow`` compared to ``Softweave``. + + +Model +""""""""""""""""""" + +Some ESC/P2 printers such as the Stylus 800 do not offer ``Microweave`` or the commands required to do ``Softweave``. Setting ``Model`` just changes the defaults and omits some parts of the initialization sequence which are not compatible with the given printer model. Currently only ":title:`st800`" is supported besides the default :title:`stcolor`. + + +Bugs and pitfalls +~~~~~~~~~~~~~~~~~~~~~ + + +- The given ``?coding`` and ``?transfer`` arrays should be strictly monotonic. + +- It is impossible to change ``WHITE``: that's your paper. Thus RGB transfer should end at 1.0 and CMYK transfer should start at 0.0. + +- Usually 8 bits per component yields fastest operation. + +- The ``ColorAdjustMatrix`` is not used in the reverse transformation used when Ghostscript does the dithering (``gs*`` modes). Expect funny results. + +- If ``BitsPerPixel`` is less than 6, the entire coding and transfer process does not work. This is always true for the ``gs*`` modes and becomes true for the other modes if ``BitsPerPixel`` is forced to low values. + +- 720×720dpi printing should never select the ``gs*`` modes and should always use ``stcolor.ps``. (I prefer 360×720.) + + +Tests +~~~~~~~~~~~~~~~~~~~~~ + +This section gives an overview of performance in terms of processing and printing times, from tests run after version 1.13. Printing was done offline (simply copying a processed file to the printer) to measure real printing speed without regard to speed of processing on the host, since at high resolutions, processing time is the same order of magnitude and thus may become the limiting factor. + +**The various OutputCodes** + +I ran several files though Ghostscript and recorded the size of the resulting print code, the processing time, and the printing time, at least for some of the files, always using these options: + + +.. code-block:: bash + + gs -sDEVICE=stcolor -sPAPERSIZE=a4 stcolor.ps - < file.ps + +(Actually "``-sPAPERSIZE=a4``" is in my ``gs_init.ps`` since I'm a germ.) + + +"``deltarow``" is the new encoding principle ("``ESC . 3 10 10 1``") with ``Microweave`` on. It is activated with "``-sOutputCode=deltarow``". + +"``Softweave``" actually means that nothing else was used: it is the default, and implies that odd v=40/h=10/m=15 mode ("``ESC . 1 40 10 15``"). + +"``Microweave``" means "``-dMicroweave``", equivalent to "``ESC . 1 10 10 1``", with full skip optimization and microweave activated. + + +Finally I wanted to see the plain `Kathy Ireland`_, and used "``-sOutputCode=plain``", which just replaces runlength encoding (RLE) by no encoding, thus using "``ESC . 0 40 10 15``". [So sorry ;-) Kathy was still dressed in blue in front of the blue sea on a blue air cushion – nice to see but hard to dither.] + + +So here are the results. + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="5">File sizes and printing speeds with various weaving methods</th> + </tr> + <tr> + <td> </td> + <td><code>golfer.ps</code></td> + <td><code>colorcir.ps</code></td> + <td><code>drawing.ps</code></td> + <td><code>brief.ps</code></td> + </tr> + <tr> + <td><code>deltarow</code></td> + <td>572751/48.180u</td> + <td>643374/41.690u</td> + <td>90142/46.180u/1:50</td> + <td>178563/49.350u/2:22</td> + </tr> + <tr> + <td><code>Softweave</code></td> + <td>559593/46.810u</td> + <td>669966/44.960u</td> + <td>296168/48.160u/1:30</td> + <td>269808/43.320u/1:55</td> + </tr> + <tr> + <td><code>Microweave</code></td> + <td>590999/56.060u</td> + <td>754276/42.890u</td> + <td>338885/47.060u/1:50</td> + <td>282314/44.690u/2:22</td> + </tr> + </table> + + +| + +.. _Kathy Ireland: + +.. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="2">Kathy Ireland</th> + </tr> + <tr> + <td></td> + <td><code>kathy.ps</code></td> + </tr> + <tr> + <td><code>deltarow</code></td> + <td>3975334/111.940u/5:35</td> + </tr> + <tr> + <td><code>Softweave</code></td> + <td>3897112/101.940u/3:10</td> + </tr> + <tr> + <td><code>Microweave</code></td> + <td>4062829/100.990u/3:15</td> + </tr> + <tr> + <td><code>plain/soft</code></td> + <td>5072255/104.390u/3:05</td> + </tr> + </table> + + +| + + +It may be that I've not chosen the optimal ``deltarow`` code, but even if it saves at lot of bytes, printing-speed is not increased. + +At least the printer prefers plain Kathy. In other words, sending 1 Megabyte or 20% more data has no impact on printing speed. ``drawing.ps`` is an exception to this rule: plain prints slower than RLE. + +"Unclever" coding -- especially with ``deltarow`` -- can significantly slow down printing. But even if very significant advantages in the size of the code are achieved, ``deltarow`` is not competitive. ``colorcir.ps`` shows savings with ``deltarow``, but printing is a mess. + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="6">Printing time related to other options <small>(*Full page halftone images printed, unless otherwise noted.)</small></th> + </tr> + <tr> + <th align="right">dpi</th> + <th align="right">Print mode</th> + <th align="right">Size KB</th> + <th align="right">Time</th> + <th colspan="2" align="left">Comments</th> + </tr> + <tr> + <td align="right">180x180 mono</td> + <td align="right">-/uni</td> + <td align="right">358</td> + <td align="right">1:15</td> + <td colspan="2"> </td> + </tr> + <tr> + <td> </td> + <td align="right">-/bi</td> + <td align="right">358</td> + <td align="right">0:45</td> + <td colspan="2"> </td> + </tr> + <tr> + <td> </td> + <td align="right">micro/bi</td> + <td align="right">205</td> + <td align="right">0:45</td> + <td colspan="2">Not Weaving</td> + </tr> + <tr> + <td> </td> + <td align="right">soft/bi</td> + <td align="right">179</td> + <td align="right">1:25</td> + <td colspan="2"> </td> + </tr> + <tr> + <td align="right">color</td> + <td align="right">-/bi</td> + <td align="right">641</td> + <td align="right">2:45</td> + <td colspan="2"> </td> + </tr> + <tr> + <td> </td> + <td align="right">soft/bi</td> + <td align="right">556</td> + <td align="right">1:32</td> + <td colspan="2"> </td> + </tr> + <tr> + <td align="right">360x360 mono</td> + <td align="right">-/uni</td> + <td align="right">269</td> + <td align="right">0:50</td> + <td colspan="2">Monochrome text</td> + </tr> + <tr> + <td> </td> + <td align="right">-/bi</td> + <td align="right">269</td> + <td align="right">0:35</td> + <td colspan="2">Monochrome text</td> + </tr> + <tr> + <td> </td> + <td align="right">micro/bi</td> + <td align="right">269</td> + <td align="right">2:25</td> + <td colspan="2">Monochrome text</td> + </tr> + <tr> + <td> </td> + <td align="right">soft/uni</td> + <td align="right">250</td> + <td align="right">3:15</td> + <td colspan="2">Monochrome text</td> + </tr> + <tr> + <td> </td> + <td align="right">soft/bi</td> + <td align="right">250</td> + <td align="right">1:55</td> + <td colspan="2">Monochrome text</td> + </tr> + <tr> + <td align="right">color</td> + <td align="right">-/bi</td> + <td align="right">346</td> + <td align="right">1:00</td> + <td colspan="2">Sparse-color page, visible displacements</td> + </tr> + <tr> + <td> </td> + <td align="right">micro/bi</td> + <td align="right">346</td> + <td align="right">1:50</td> + <td colspan="2">Sparse-color page, looks buggy – printer?</td> + </tr> + <tr> + <td> </td> + <td align="right">soft/bi</td> + <td align="right">294</td> + <td align="right">1:30</td> + <td colspan="2">Sparse-color page, O.K.</td> + </tr> + <tr> + <td> </td> + <td align="right">-/bi</td> + <td align="right">2218</td> + <td align="right">2:45</td> + <td colspan="2">Visible stripes</td> + </tr> + <tr> + <td> </td> + <td align="right">micro/bi</td> + <td align="right">5171</td> + <td align="right">3:17</td> + <td colspan="2"> </td> + </tr> + <tr> + <td> </td> + <td align="right">soft/bi</td> + <td align="right">3675</td> + <td align="right">3:05</td> + <td colspan="2"> </td> + </tr> + <tr> + <td align="right">360x720 mono</td> + <td align="right">soft/bi</td> + <td align="right">2761</td> + <td align="right">5:40</td> + <td colspan="2"> </td> + </tr> + <tr> + <td align="right">color</td> + <td align="right">soft/bi</td> + <td align="right">7789</td> + <td align="right">6:15</td> + <td colspan="2">Just a small difference!</td> + </tr> + <tr> + <td align="right">720x360 color</td> + <td align="right">soft/bi</td> + <td align="right">7182</td> + <td align="right">5:40</td> + <td colspan="2"> </td> + </tr> + <tr> + <td align="right">720x720 color</td> + <td align="right">micro/bi</td> + <td align="right">14748</td> + <td align="right">30:26</td> + <td colspan="2">Actually beyond printer's capabilities</td> + </tr> + <tr> + <td> </td> + <td align="right">soft/bi</td> + <td align="right">14407</td> + <td align="right">11:08</td> + <td colspan="2"> </td> + </tr> + </table> + + + +Acknowledgments +~~~~~~~~~~~~~~~~~~~~~~~~ + +This driver was copied from ``gdevcdj.c`` (Ghostscript 3.12), which was contributed by George Cameron, Koert Zeilstra, and Eckhard Rueggeberg. Some of the ESC/P2 code was drawn from Richard Brown's ``gdevescp.c``. The POSIX interrupt code (compilation option -DSTC_SIGNAL) is from Frederic Loyer. Several improvements are based on discussions with Brian Converse, Bill Davidson, Gero Guenther, Jason Patterson, ? Rueschstroer, and Steven Singer. + +While I wish to thank everyone mentioned above, they are by no means responsible for bugs in the :title:`stcolor` driver -- just for the features. + + +.. _uniprint: + + +uniprint, a flexible unified printer driver +---------------------------------------------------- + +:title:`uniprint` is a unified parametric driver by `Gunther Hess`_ for several kinds of printers and devices, including: + +- Any Epson Stylus Color, Stylus, or Stylus Pro. +- HP PCL/RTL. +- Canon BubbleJet Color 610. +- NEC P2X. +- Sun raster file format. + +This driver is intended to become a unified printer driver. If you consider it ugly, please send me your suggestions for improvements. The driver will be updated with them. Thus the full explanation of the driver's name is: Ugly- -> Updated- -> Unified Printer Driver + + +But you probably want to know something about the functionality. At the time of this writing :title:`uniprint` drives: + +- NEC Pinwriter P2X (24-pin monochrome impact printer, ESC/P style). +- Several Epson Stylus Color models (ESC/P2 style). +- HP-DeskJet 550c (basic HP-RTL). +- Canon BJC 610. + +It can be configured for various other printers without recompilation and offers uncompressed (ugly) Sun rasterfiles as another format, but this format is intended for testing purposes rather than real use. The usage of this driver is quite simple. The typical command line looks like this: + + +.. code-block:: bash + + gs @{MODEL}.upp -sOutputFile={printable file} MyFile.ps -c quit + + +For example, from my Linux box: + +.. code-block:: bash + + gs @stc.upp -sOutputFile=/dev/lp1 tiger.eps -c quit + + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="3">Unified Printer Parameter files distributed with Ghostscript</th> + </tr> + <tr> + <th align="left" colspan="3">Canon BJC 610 (color, rendered)</th> + </tr> + <tr> + + <td><code>bjc610a0.upp</code></td> + + <td>360×360dpi</td> + + <td>plain paper, high speed</td> + </tr> + <tr> + + <td><code>bjc610a1.upp</code></td> + + <td>360×360dpi</td> + + <td>plain paper</td> + </tr> + <tr> + + <td><code>bjc610a2.upp</code></td> + + <td>360×360dpi</td> + + <td>coated paper</td> + </tr> + <tr> + + <td><code>bjc610a3.upp</code></td> + + <td>360×360dpi</td> + + <td>transparency film</td> + </tr> + <tr> + + <td><code>bjc610a4.upp</code></td> + + <td>360×360dpi</td> + + <td>back print film</td> + </tr> + <tr> + + <td><code>bjc610a5.upp</code></td> + + <td>360×360dpi</td> + + <td>fabric sheet</td> + </tr> + <tr> + + <td><code>bjc610a6.upp</code></td> + + <td>360×360dpi</td> + + <td>glossy paper</td> + </tr> + <tr> + + <td><code>bjc610a7.upp</code></td> + + <td>360×360dpi</td> + + <td>high gloss film</td> + </tr> + <tr> + + <td><code>bjc610a8.upp</code></td> + + <td>360×360dpi</td> + + <td>high resolution paper</td> + </tr> + <tr> + <th colspan="3"></th> + </tr> + <tr> + + <td><code>bjc610b1.upp</code></td> + + <td>720×720dpi</td> + + <td>plain paper</td> + </tr> + <tr> + + <td><code>bjc610b2.upp</code></td> + + <td>720×720dpi</td> + + <td>coated paper</td> + </tr> + <tr> + + <td><code>bjc610b3.upp</code></td> + + <td>720×720dpi</td> + + <td>transparency film</td> + </tr> + <tr> + + <td><code>bjc610b4.upp</code></td> + + <td>720×720dpi</td> + + <td>back print film</td> + </tr> + <tr> + + <td><code>bjc610b6.upp</code></td> + + <td>720×720dpi</td> + + <td>glossy paper</td> + </tr> + <tr> + + <td><code>bjc610b7.upp</code></td> + + <td>720×720dpi</td> + + <td>high-gloss paper</td> + </tr> + <tr> + + <td><code>bjc610b8.upp</code></td> + + <td>720×720dpi</td> + + <td>high resolution paper</td> + </tr> + <tr> + <th align="left" colspan="3">HP Ink-Printers</th> + </tr> + <tr> + + <td><code>cdj550.upp</code></td> + + <td>300×300dpi</td> + + <td>32-bit CMYK</td> + </tr> + <tr> + + <td><code>cdj690.upp</code></td> + + <td>300×300dpi</td> + + <td>Normal mode</td> + </tr> + <tr> + + <td><code>cdj690ec.upp</code></td> + + <td>300×300dpi</td> + + <td>Economy mode</td> + </tr> + <tr> + + <td><code>dnj750c.upp</code></td> + + <td>300×300dpi</td> + + <td>Color – also good for 450C</td> + </tr> + <tr> + + <td><code>dnj750m.upp</code></td> + + <td>600×600dpi</td> + + <td>Monochrome</td> + </tr> + <tr> + <th align="left" colspan="3">NEC P2X</th> + </tr> + <tr> + + <td><code>necp2x.upp</code></td> + + <td>360×360dpi</td> + + <td>8-bit (Floyd-Steinberg)</td> + </tr> + <tr> + <th align="left" colspan="3">Any Epson Stylus Color</th> + </tr> + <tr> + + <td><code>stcany.upp</code></td> + + <td>360×360dpi</td> + + <td>4-bit, PostScript halftoning</td> + </tr> + <tr> + + <td><code>stcany_h.upp</code></td> + + <td>720×720dpi</td> + + <td>4-bit, PostScript halftoning</td> + </tr> + <tr> + <th align="left" colspan="3">Original Epson Stylus and Stylus Pro Color</th> + </tr> + <tr> + + <td><code>stc.upp</code></td> + + <td>360×360dpi</td> + + <td>32-bit CMYK, 15-pin</td> + </tr> + <tr> + + <td><code>stc_l.upp</code></td> + + <td>360×360dpi</td> + + <td>4-bit, PostScript halftoning, weaved noWeave</td> + </tr> + <tr> + + <td><code>stc_h.upp</code></td> + + <td>720×720dpi</td> + + <td>32-bit CMYK, 15-pin Weave</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color II</th> + </tr> + <tr> + + <td><code>stc2.upp</code></td> + + <td>360×360dpi</td> + + <td>32-bit CMYK, 20-pin, Epson Stylus Color II(s)</td> + </tr> + <tr> + + <td><code>stc2_h.upp</code></td> + + <td>720×720dpi</td> + + <td>32-bit CMYK, 20-pin, Epson Stylus Color II</td> + </tr> + <tr> + + <td><code>stc2s_h.upp</code></td> + + <td>720×720dpi</td> + + <td>32-bit CMYK, 20-pin, Epson Stylus Color IIs</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color 200</th> + </tr> + <tr> + + <td><code>stc200.upp</code></td> + + <td>360×720dpi</td> + + <td>Plain Paper</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color 300</th> + </tr> + <tr> + + <td><code>stc300.upp</code></td> + + <td>360×360dpi</td> + + <td>32-bit CMYK, plain paper</td> + </tr> + <tr> + + <td><code>stc300bl.upp</code></td> + + <td>180×180dpi</td> + + <td>black only, plain paper</td> + </tr> + <tr> + + <td><code>stc300bm.upp</code></td> + + <td>360×360dpi</td> + + <td>black only, plain paper</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color 500 (good transfer curves for plain paper)</th> + </tr> + <tr> + + <td><code>stc500p.upp</code></td> + + <td>360×360dpi</td> + + <td>32-bit CMYK, noWeave, plain paper</td> + </tr> + <tr> + + <td><code>stc500ph.upp</code></td> + + <td>720×720dpi</td> + + <td>32-bit CMYK, noWeave, plain paper</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color 600, 32/90-inch weaving</th> + </tr> + <tr> + + <td><code>stc600pl.upp</code></td> + + <td>360×360dpi</td> + + <td>32-bit CMYK, 32-pin, plain paper</td> + </tr> + <tr> + + <td><code>stc600p.upp</code></td> + + <td>720×720dpi</td> + + <td>32-bit CMYK, 32-pin, plain paper</td> + </tr> + <tr> + + <td><code>stc600ih.upp</code></td> + + <td>1440×720dpi</td> + + <td>32-bit CMYK, 30-pin, inkjet paper</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color 640</th> + </tr> + <tr> + + <td><code>stc640p.upp</code></td> + + <td>720×720dpi</td> + + <td>plain paper?</td> + </tr> + <tr> + + <td><code>st640p.upp</code></td> + + <td>720×720dpi</td> + + <td>CMYK, plain paper</td> + </tr> + <tr> + + <td><code>st640pg.upp</code></td> + + <td>720×720dpi</td> + + <td>grayscale, plain paper</td> + </tr> + <tr> + + <td><code>st640pl.upp</code></td> + + <td>360×360dpi</td> + + <td>CMYK, plain paper</td> + </tr> + <tr> + + <td><code>st640plg.upp</code></td> + + <td>360×360dpi</td> + + <td>grayscale, plain paper</td> + </tr> + <tr> + + <td><code>st640ih.upp</code></td> + + <td>1440×720dpi</td> + + <td>CMYK, inkjet paper</td> + </tr> + <tr> + + <td><code>st640ihg.upp</code></td> + + <td>1440×720dpi</td> + + <td>grayscale, inkjet paper</td> + </tr> + <tr> + <th align="left" colspan="3">Epson Stylus Color 800, 64/180-inch weaving</th> + </tr> + <tr> + + <td><code>stc800pl.upp</code></td> + + <td>360×360dpi</td> + + <td>32-bit CMYK, 64-pin, plain paper</td> + </tr> + <tr> + + <td><code>stc800p.upp</code></td> + + <td>720×720dpi</td> + + <td>32-bit CMYK, 64-pin, plain paper</td> + </tr> + <tr> + + <td><code>stc800ih.upp</code></td> + + <td>1440×720dpi</td> + + <td>32-bit CMYK, 62-pin, inkjet paper</td> + </tr> + <tr> + + <td><code>stc1520.upp</code></td> + + <td>1440×720dpi</td> + + <td>32-bit CMYK, 62-pin, inkjet paper</td> + </tr> + <tr> + <th align="left" colspan="3">Sun raster file</th> + </tr> + <tr> + + <td><code>ras1.upp</code></td> + + <td>1-bit</td> + + <td>monochrome (Ghostscript)</td> + </tr> + <tr> + + <td><code>ras3.upp</code></td> + + <td>3-bit</td> + + <td>RGB (Ghostscript)</td> + </tr> + <tr> + + <td><code>ras4.upp</code></td> + + <td>4-bit</td> + + <td>CMYK (Ghostscript)</td> + </tr> + <tr> + + <td><code>ras8m.upp</code></td> + + <td>8-bit</td> + + <td>grayscale (Floyd-Steinberg)</td> + </tr> + <tr> + + <td><code>ras24.upp</code></td> + + <td>24-bit</td> + + <td>RGB (Floyd-Steinberg)</td> + </tr> + <tr> + + <td><code>ras32.upp</code></td> + + <td>32-bit</td> + + <td>CMYK (CMYK-Floyd-Steinberg)</td> + </tr> + </table> + + +| + + +Thanks to Danilo Beuche, Guido Classen, Mark Goldberg and Hans-Heinrich Viehmann for providing the files for the ``stc200``, ``hp690``, ``stc500`` and the ``stc640``. Thanks to `Michael Lossin`_ for the newer ``st640`` parameter sets. + + +.. note:: + + - Changing the resolution with Ghostscript's ``-r`` switch is usually not possible. + + - For Epson Stylus Color models not listed above, the two ``stc500`` variants are likely to work in addition to ``stcany``, but their gamma correction might be wrong. + + +The state of this driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The coding of :title:`uniprint` was triggered by the requirements of the various Stylus Color models and some personal needs for HP and NEC drivers. Thus the Epson models are well represented among the distributed parameter files. When this driver entered the beta test phase, three other drivers appeared on the scene that could be at least partially integrated into :title:`uniprint`: :title:`cdj850` by Uli Wortmann, ``hpdj`` by Martin Lottermoser, and ``bjc610`` by Helmut Riegler. + +Uli addresses features of the more recent DeskJet models that will not be available in :title:`uniprint` soon. Martin taught me a lesson on HP-PCL3 headers that will be available in :title:`uniprint` soon. Helmut in turn followed an almost similar idea, but targetted primarily for printing on Canon printers from the ``pbmplus`` library. Starting with version 1.68 of :title:`uniprint`, BJC support is available. Work on the ``hpdj`` integration will start after the update of my website. + + +Notes on :title:`uniprint`'s background +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:title:`uniprint` is actually an update of :title:`stcolor`, but much more versatile than its predecessor; :title:`stcolor`, in its turn, started as a clone of the color DeskJet family of drivers (``cdj*``). Finally, ``cdj*`` can be considered an addition of features to the simpler monochrome drivers of Ghostscript. This addition of features is useful to get an idea of the functionality of :title:`uniprint`: + +Monochrome to advanced color (``cdj*``) + This adds color mapping and rendering functions to the driver. Error diffusion is especially important for the quality of printing. + +HP color to Epson Color (:title:`stcolor`) + The Epson Stylus Color offered two features simultaneously: it could produce 720×720dpi output and it could soak the paper. In other words, it required more color management features inside the driver. This is still the major conceptual difference in the data generation for HP and Epson printers. + +Weaving techniques (:title:`stcolor`) + Besides the internal color management, the Stylus Color did not provide enough buffer space to operate the printer fast at 720×720dpi. The use of weaving could yield triple the print speed. Weaving, also called interleaving, is present in some monochrome drivers too. The new thing in :title:`stcolor` was the combination with error diffusion. Unfortunately the weaving was somehow hard-coded, as the problems with the newer members of the Stylus Color family of printers demonstrated. + +Generalized output format and weaving (:title:`uniprint`) + The features mentioned above yield about 90% of :title:`stcolor`'s source code; only 10% is related to the formatting of the output. The idea to make the output format switchable came up soon after completing stcolor, but its final design was triggered by the (personal) necessity to drive a NEC P2X and a Designjet 750c. + + +Thus :title:`uniprint` accumulates almost any features that can be found among the other printer drivers, which clearly has some disadvantage in processing speed -- true in particular of version 1.75, since it was targetted for functionality, and several speed-gaining features were (knowingly) omitted. + +To summarize and to introduce the terms used in the description of the parameters, the features of :title:`uniprint` that can be parameterized are: + +- Color mapping. +- Color rendering (error diffusion or Floyd-Steinberg). +- Output format, including weaving. + + +Godzilla's guide to the creation of Unified Printer Parameter (``.upp``) files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is one of the distributed parameter files (``stc_l.upp``) with some added comments. Also see the section that describes all :title:`uniprint`'s parameters in brief. + + +.. code-block:: + + -supModel="Epson Stylus Color I (and PRO Series), 360x360DpI, noWeave" + -sDEVICE=uniprint -- Select the driver + -dNOPAUSE -- Useful with printers + -dSAFER -- Provides some security + -dupColorModel=/DeviceCMYK -- Selects the color mapping + -dupRendering=/ErrorDiffusion -- Selects the color rendering + -dupOutputFormat=/EscP2 -- Selects the output format + -r360x360 -- Adjusts the resolution + -dupMargins="{ 9.0 39.96 9.0 9.0}" -- Establishes (L/B/R/T margins in points) + -dupComponentBits="{1 1 1 1}" -- Map: bits per component (default: 8) + -dupWeaveYPasses=4 -- Weave: Y-passes (default: 1) + -dupOutputPins=15 -- Format/weave: scans per Command + -dupBeginPageCommand="< -- Goes to the printer + 1b40 1b40 -- ESC '@' ESC '@' -> dual reset + 1b2847 0100 01 -- ESC '(' 'G' 1 0 1 -> graphics + 1b2869 0100 00 -- ESC '(' 'i' 1 0 1 -> no HW weave + 1b2855 0100 0A -- ESC '(' 'U' 1 0 10 -> 360dpi + 1b5500 -- ESC 'U' 0 -> bidir print + 1b2843 0200 0000 -- ESC '(' 'C' 2 0 xx -> page length + 1b2863 0400 0000 0000 -- ESC '(' 'c' 4 0 xxxx -> margins + >" -- as it is, unless: + -dupAdjustPageLengthCommand -- Adjust page length in BOP requested + -dupAdjustTopMarginCommand -- Adjust top margin in BOP + -dupAdjustBottomMarginCommand -- Adjust bottom margin in BOP + -dupEndPageCommand="(\033@\014)" -- Last (but one) data to the printer + -dupAbortCommand="(\033@\15\12\12\12\12 Printout-Aborted\15\014)" + + +That's short, and if one removes ``upWeaveYPasses`` and ``upOutputPins`` it becomes shorter, almost ``stcany.upp``. This miniature size is because I am most familiar with ESC/P2, and was able to add defaults for the omitted parameters. Now a few notes about the parameters used in this example: + + +- ``upModel`` is a string serving as a comment (and nothing else). +- ``DEVICE``, ``NOPAUSE``, ``SAFER`` are well-known Ghostscript parameters described in the :ref:`usage documentation<Use.htm>`. +- ``upColorModel`` is one of the major :title:`uniprint` parameters: it selects the color mapping and in turn the PostScript color model. It supports the devices ``/DeviceGray``, ``/DeviceRGBW``, ``/DeviceRGB``, ``/DeviceCMYK``, and ``/DeviceCMYKgenerate``. +- ``upRendering`` selects the (color) rendering, supporting the values ``/ErrorDiffusion`` and ``/FSCMYK32``. ``/ErrorDiffusion`` is similar to ``fsmono``, ``fsrgb`` and ``fsx4`` of :title:`stcolor`, while ``/FSCMYK32`` is (almost) identical to ``fscmyk`` and ``hscmyk``, but is restricted to 32-bit data and should be used in conjunction with ``/DeviceCMYKgenerate``. +- ``upOutputFormat`` selects the output method, supporting the values ``/SunRaster``, ``/Epson``, ``/EscP2``, ``/EscP2XY``, and ``/Pcl``. + + + .. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - ``/SunRaster`` + - creates Sun raster files and requires no other parameters + * - ``/Epson`` + - is used for the elderly ESC/P format (used by many printers) + * - ``/EscP2`` + - is used by more recent Epson printers (no X weaving supported) + * - ``/EscP2XY`` + - supports X-Weaving, used with 1440dpi printers and in ``stc2s_h`` + * - ``/Pcl`` + - HP PCL/RTL-style output formatter without weaving + + + +- ``-r360x360`` is Ghostscript's standard resolution switch. +- ``upMargins="{ 9.0 39.96 9.0 9.0}"`` has function similar to the Ghostscript parameter ``.HWMargins``: it sets the left, bottom, right, and top margins in points. :title:`uniprint` provides this parameter to enable automatic left-right exchange if ``upYFlip`` is active. +- ``upComponentBits`` is an array of integers that selects the bits stored in raster memory, by default 8 bits per component. In this example, 1 bit is selected for each component, thus turning down the Floyd-Steinberg algorithm (but still carrying out the time-consuming computation). The related parameter ``upComponentShift`` controls positioning the components within raster memory. Each of the numbers given corresponds to a component which depends on the selected ``upColorModel``: + + + .. list-table:: + :header-rows: 1 + + * - + - /DeviceGray + - /DeviceRGBW + - /DeviceRGB + - /DeviceCMYK + - /DeviceCMYKgenerate + * - 0 + - White + - White + - Red + - Black + - Black + * - 1 + - -- + - Red + - Green + - Cyan + - Cyan + * - 2 + - -- + - Green + - Blue + - Magenta + - Magenta + * - 3 + - -- + - Blue + - -- + - Yellow + - Yellow + + + This order may not be suitable for some printers, so another parameter ``upOutputComponentOrder``, also an array of integers, selects the output order using the numbers on the left. + + + One group of very important parameters not used in the example above deserves to be mentioned here: the transfer arrays, named ``up{color}Transfer``, where ``{color}`` is one of the names in the table above. These are arrays of floats in the range 0.0 - 1.0 representing the color transfer functions. They are used during mapping and rendering. In the simplest case, these arrays ensure an equidistant distribution of the stored values within the device space (which means a nonlinear mapping from Ghostscript's point of view). If the given array does not cover the entire range from 0 to 1, which applies for the Stylus Color family at high resolution for some media, only the relevant part gets mapped to raster memory (meaning that is's fully utilized) and the rendering takes care of the "overhang" (in this case the post-diffusion of 1-bit components makes sense). + + Finally an important note on the transfer arrays: for monochrome devices the stored component is ``White``, which is the way PostScript defines these devices, but most printers require ``Black``. Thus one has to provide a falling ``upWhiteTransfer`` for such printers. + + +- ``upWeaveYPasses`` is an integer that gives the number of print head passes required to achieve the requested ``Ydpi``. This makes sense only if ``upOutputPins`` is set to something greater than 1. Thus multiple pins or nozzles are transferred with a single command, and of course such a command must be supported by the device. + + +If no other weave parameters are given, :title:`uniprint` computes several defaults which together do no weaving. The ``/Epson`` and ``/EscP2XY`` formats take care of ``upWeaveXPasses`` too. + + +- ``upBeginPageCommand`` represents the data transferred to the printer whenever a new page begins. Before that, ``upBeginJobCommand`` is written to the device only once per output file. (Intended for the HP PJL sequences). + +- ``upAdjustBottomMarginCommand``, ``upAdjustMediaSize``, ``upAdjustPageLengthCommand``, ``upAdjustPageWidthCommand``, ``upAdjustResolutionCommand``, and ``upAdjustTopMarginCommand``. + + Normally :title:`uniprint` does not change the ``upBeginPageCommand``, nor does it provide a default. However, if the above boolean values are set, the corresponding values are changed (provided that the code of the formatters supports this change and the commands to be adjusted are included in the BOP string). + +- ``upEndPageCommand`` is the fixed termination sequence for each page, and of course there is an ``upEndJobCommand`` too. + +- ``upAbortCommand`` is written if :title:`uniprint`'s interrupt detection is enabled and a signal is caught. It replaces ``upEndPageCommand`` and ``upEndJobCommand``, thus allowing the indication of an aborted job. (Ghostscript gets an error return from :title:`uniprint` in this case, and abandons further processing). + + +For the ESC/P(2) formats all commands represent binary data, while for the PCL/RTL formatter some of them are formats for ``fprintf``. These strings must explicitly have a trailing ``"\0'``. + +I should write more, but the only recommendation is to take a look at the various parameter files. Here are a few more hints. + +- If the Driver rejects a configuration, nothing happens until showpage; then an error is raised and a message with ``CALL-REJECTED upd_print_page...`` is printed on ``stderr``. +- :title:`uniprint` has lots of messages that can be activated by setting bits in the preprocessor macro ``UPD_MESSAGES``. I usually use the compile-time option ``-DUPD_MESSAGES=0x17`` for configuration development. (For the semantics, check the ``UPD_M_`` macros in the source). +- A program ``"uninfo.ps"`` distributed with Ghostscript displays interactively in alphabetical order the contents of the current ``pagedevice`` dictionary. This includes any parameters generated or changed by :title:`uniprint`. + + + +All parameters in brief +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This table gives a brief explanation of every parameter known to :title:`uniprint`, listing them in alphabetical order. "``[ ]``" denotes that a parameter is an array, and "``(RO)``" that it is read-only. + + + +.. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="3">All uniprint parameters</th> + </tr> + <tr> + <th align="left">Parameter</th> + + <th align="left">Type</th> + + <th align="left">Use</th> + </tr> + <tr> + <td><code>upAbortCommand</code></td> + + <td>String</td> + + <td>End of page and file on interrupt</td> + </tr> + <tr> + <td><code>upAdjustBottomMarginCommand</code></td> + + <td>Bool</td> + + <td>Manipulate bottom margin in <code>upBeginPageCommand</code></td> + </tr> + <tr> + <td><code>upAdjustMediaSizeCommand</code></td> + + <td>Bool</td> + + <td>Manipulate <code>Mediasize</code> [intended]</td> + </tr> + <tr> + <td><code>upAdjustPageLengthCommand</code></td> + + <td>Bool</td> + + <td>Manipulate page length in <code>upBeginPageCommand</code></td> + </tr> + <tr> + <td><code>upAdjustPageWidthCommand</code></td> + + <td>Bool</td> + + <td>Manipulate page width in <code>upBeginPageCommand</code></td> + </tr> + <tr> + <td><code>upAdjustResolutionCommand</code></td> + + <td>Bool</td> + + <td>Manipulate resolution</td> + </tr> + <tr> + <td><code>upAdjustTopMarginCommand</code></td> + + <td>Bool</td> + + <td>Manipulate top margin in <code>upBeginPageCommand</code></td> + </tr> + <tr> + <td><code>upBeginJobCommand</code></td> + + <td>String</td> + + <td>Begin each output file</td> + </tr> + <tr> + <td><code>upBeginPageCommand</code></td> + + <td>String</td> + + <td>Begin each page</td> + </tr> + <tr> + <td><code>upBlackTransfer</code></td> + + <td>Float[ ]</td> + + <td>Black transfer (CMYK only!)</td> + </tr> + <tr> + <td><code>upBlueTransfer</code></td> + + <td>Float[ ]</td> + + <td>Blue transfer</td> + </tr> + <tr> + <td><code>upColorInfo</code></td> + + <td>Int[ ]</td> + + <td>struct <code>gx_device_color_info</code></td> + </tr> + <tr> + <td><code>upColorModel</code></td> + + <td>Name</td> + + <td>Select color mapping</td> + </tr> + <tr> + <td><code>upColorModelInitialized</code></td> + + <td>Bool (RO)</td> + + <td>Color mapping OK</td> + </tr> + <tr> + <td><code>upComponentBits</code></td> + + <td>Int[ ]</td> + + <td>Bits stored per component</td> + </tr> + <tr> + <td><code>upComponentShift</code></td> + + <td>Int[ ]</td> + + <td>Positioning within <code>gx_color_index</code></td> + </tr> + <tr> + <td><code>upCyanTransfer</code></td> + + <td>Float[ ]</td> + + <td>Cyan transfer</td> + </tr> + <tr> + <td><code>upEndJobCommand</code></td> + + <td>String</td> + + <td>End each file unless <code>upAbortCommand</code></td> + </tr> + <tr> + <td><code>upEndPageCommand</code></td> + + <td>String</td> + + <td>End each page unless <code>upAbortCommand</code></td> + </tr> + <tr> + <td><code>upErrorDetected</code></td> + + <td>Bool (RO)</td> + + <td>Severe (VM) error, not fully operational</td> + </tr> + <tr> + <td><code>upFSFixedDirection</code></td> + + <td>Bool</td> + + <td>Inhbits direction toggling in rendering</td> + </tr> + <tr> + <td><code>upFSProcessWhiteSpace</code></td> + + <td>Bool</td> + + <td>Causes white-space rendering</td> + </tr> + <tr> + <td><code>upFSReverseDirection</code></td> + + <td>Bool</td> + + <td>Run rendering in reverse (if fixed)</td> + </tr> + <tr> + <td><code>upFSZeroInit</code></td> + + <td>Bool</td> + + <td>Non-random rendering initialization</td> + </tr> + <tr> + <td><code>upFormatXabsolute</code></td> + + <td>Bool</td> + + <td>Write absolute X coordinates</td> + </tr> + <tr> + <td><code>upFormatYabsolute</code></td> + + <td>Bool</td> + + <td>Write absolute Y coordinates</td> + </tr> + <tr> + <td><code>upGreenTransfer</code></td> + + <td>Float[ ]</td> + + <td>Green transfer</td> + </tr> + <tr> + <td><code>upMagentaTransfer</code></td> + + <td>Float[ ]</td> + + <td>Magenta transfer</td> + </tr> + <tr> + <td><code>upMargins</code></td> + + <td>Float[ ]</td> + + <td>L/B/R/T margins in points</td> + </tr> + <tr> + <td><code>upModel</code></td> + + <td>String</td> + + <td>Comment string, holds some info</td> + </tr> + <tr> + <td><code>upOutputAborted</code></td> + + <td>Bool (RO)</td> + + <td>Caught an interrupt</td> + </tr> + <tr> + <td><code>upOutputBuffers</code></td> + + <td>Int</td> + + <td>Number of rendering buffers (2^<small><sup><b>N</b></sup></small>)</td> + </tr> + <tr> + <td><code>upOutputComponentOrder</code></td> + + <td>Int[ ]</td> + + <td>Order of components when printing</td> + </tr> + <tr> + <td><code>upOutputComponents</code></td> + + <td>Int</td> + + <td>Number of written components, not fully operational</td> + <tr> + <td><code>upOutputFormat</code></td> + + <td>Name</td> + + <td>Select output format</td> + </tr> + <tr> + <td><code>upOutputFormatInitialized</code></td> + + <td>Bool (RO)</td> + + <td>Format data OK</td> + </tr> + <tr> + <td><code>upOutputHeight</code></td> + + <td>Int</td> + + <td>Output height in pixels</td> + </tr> + <tr> + <td><code>upOutputPins</code></td> + + <td>Int</td> + + <td>Number of pins / nozzles per command</td> + </tr> + <tr> + <td><code>upOutputWidth</code></td> + + <td>Int</td> + + <td>Output width in pixels</td> + </tr> + <tr> + <td><code>upOutputXOffset</code></td> + + <td>Int</td> + + <td>Offset in pixels, if <code>upFormatXabsolute</code></td> + </tr> + <tr> + <td><code>upOutputXStep</code></td> + + <td>Int</td> + + <td>Divisor or multiplier for X coords</td> + </tr> + <tr> + <td><code>upOutputYOffset</code></td> + + <td>Int</td> + + <td>Offset in pixels, if <code>upFormatYabsolute</code></td> + </tr> + <tr> + <td><code>upOutputYStep</code></td> + + <td>Int</td> + + <td>Divisor or multiplier for Y coords</td> + </tr> + <tr> + <td><code>upRasterBufferInitialized</code></td> + + <td>Bool (RO)</td> + + <td>GS buffer OK</td> + </tr> + <tr> + <td><code>upRedTransfer</code></td> + + <td>Float[ ]</td> + + <td>Red transfer</td> + </tr> + <tr> + <td><code>upRendering</code></td> + + <td>Name</td> + + <td>Select rendering algorithm</td> + </tr> + <tr> + <td><code>upRenderingInitialized</code></td> + + <td>Bool (RO)</td> + + <td>Rendering parameters OK</td> + </tr> + <tr> + <td><code>upSelectComponentCommands</code></td> + + <td>String[ ]</td> + + <td>Establish color (output order!)</td> + </tr> + <tr> + <td><code>upSetLineFeedCommand</code></td> + + <td>String</td> + + <td>Adjust linefeed (Epson only)</td> + </tr> + <tr> + <td><code>upVersion</code></td> + + <td>String (RO)</td> + + <td>Source code version</td> + </tr> + <tr> + <td><code>upWeaveFinalPins</code></td> + + <td>Int[ ]</td> + + <td>Number of bottom pins on EOP passes</td> + </tr> + <tr> + <td><code>upWeaveFinalScan</code></td> + + <td>Int</td> + + <td>Begin EOP passes (Y-coord)</td> + </tr> + <tr> + <td><code>upWeaveFinalXStarts</code></td> + + <td>Int[ ]</td> + + <td>X-pass indices for EOP passes</td> + </tr> + <tr> + <td><code>upWeaveFinalYFeeds</code></td> + + <td>Int[ ]</td> + + <td>Y increments for EOP passes</td> + </tr> + <tr> + <td><code>upWeaveInitialPins</code></td> + + <td>Int[ ]</td> + + <td>Number of top pins on BOP passes</td> + </tr> + <tr> + <td><code>upWeaveInitialScan</code></td> + + <td>Int</td> + + <td>End BOP passes (Y coord)</td> + </tr> + <tr> + <td><code>upWeaveInitialXStarts</code></td> + + <td>Int[ ]</td> + + <td>X-pass indices for BOP passes</td> + </tr> + <tr> + <td><code>upWeaveInitialYFeeds</code></td> + + <td>int[ ]</td> + + <td>Y increments for BOP passes</td> + </tr> + <tr> + <td><code>upWeavePasses</code></td> + + <td>Int</td> + + <td>XPasses × YPasses</td> + </tr> + <tr> + <td><code>upWeaveXPasses</code></td> + + <td>Int</td> + + <td>Number of X passes</td> + </tr> + <tr> + <td><code>upWeaveXStarts</code></td> + + <td>Int[ ]</td> + + <td>X-pass indices for normal passes</td> + </tr> + <tr> + <td><code>upWeaveYFeeds</code></td> + + <td>Int[ ]</td> + + <td>Y increments for normal passes</td> + </tr> + <tr> + <td><code>upWeaveYOffset</code></td> + + <td>Int</td> + + <td>Number of blank or incomplete scans at BOP</td> + </tr> + <tr> + <td><code>upWeaveYPasses</code></td> + + <td>Int</td> + + <td>Number of X passes</td> + </tr> + <tr> + <td><code>upWhiteTransfer</code></td> + + <td>Float[ ]</td> + + <td>White transfer (monochrome devices!)</td> + </tr> + <tr> + <td><code>upWriteComponentCommands</code></td> + + <td>String[ ]</td> + + <td>Commands to write each component</td> + </tr> + <tr> + <td><code>upWroteData</code></td> + + <td>Bool (RO)</td> + + <td>Something (<code>BeginJob</code>) written to output</td> + </tr> + <tr> + <td><code>upXMoveCommand</code></td> + + <td>String</td> + + <td>X positioning command</td> + </tr> + <tr> + <td><code>upXStepCommand</code></td> + + <td>String</td> + + <td>Single step to the right</td> + </tr> + <tr> + <td><code>upYFlip</code></td> + + <td>Bool</td> + + <td>Flips output along the Y axis</td> + </tr> + <tr> + <td><code>upYMoveCommand</code></td> + + <td>String</td> + + <td>Y positioning command</td> + </tr> + <tr> + <td><code>upYStepCommand</code></td> + + <td>String</td> + + <td>Single step down</td> + </tr> + <tr> + <td><code>upYellowTransfer</code></td> + + <td>Float[ ]</td> + + <td>Yellow transfer</td> + </tr> + </table> + + + +:title:`uniprint`'s Roll of Honor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I should mention all of the people who were involved in :title:`stcolor`'s evolution, but I've decided to start from scratch here for :title:`uniprint`: + +John P. Beale + for testing the ``stc600`` modes + +Bill Davidson + who triggered some weaving research and tested ``stc2s_h`` + +`L. Peter Deutsch`_ + who triggered ease of configuration + +Mark Goldberg + who prepared the ``stc500`` transfers + +Scott F. Johnston and Scott J. Kramer + for testing the ``stc800`` modes + +Martin Lottermoser + for his great commented H-P DeskJet driver + +Helmut Riegler + for the BJC extension + +Hans-Gerd Straeter + for some measured transfer curves and more + +Uli Wortmann + for discussions and his :title:`cdj850` driver + +My family + for tolerating my printer-driver hacking + + +`Gunther Hess`_ +Duesseldorfer Landstr. 16b, D-47249 Duisburg ,Germany, +49 203 376273 telephone (MET evening hours) + + + +Uniprint weaving parameters HowTo +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section was contributed by Glenn Ramsey. + +I wrote this because the documentation was very brief and I really struggled with it for a while, but it is very simple once you understand what is going on. + +This only describes how to work out the Y parameters, I haven't looked at the X parameters yet. + + + +1. Determine the nozzle geometry (``upOutputPins``) + You need to know how many nozzles the printer has and the spacing between them. Usually you can find this out from the printer manual, or the printer supplier, but you may have to dissect a couple of printer output files produced with the driver supplied with the printer. There is a utility called ``escp2ras*`` that will help with that. Sometimes the term pin is used instead of nozzle but they mean the same thing. + + The number of nozzles will be the value assigned to the ``upOutputPins`` parameter. + + Actually you don't have to print with all the pins available but for the purpose of demonstration I'll assume that we are using them all. + +2. Determine how many passes are required (``upWeaveYPasses``). + +3. The number of passes required is going to depend on the required resolution and the nozzle spacing. + + + .. code-block:: + + passes = resolution * nozzle spacing + + This will be the value assigned to the ``upWeaveYPasses`` parameter. + + For example if the desired resolution is 360 dpi and the nozzles are spaced at 1/90in then 360 * 1/90 = 4 passes are required. For 720 dpi 8 passes would be required. The printer would, of course, have to be capable of moving the paper in increments of either 360 or 720 dpi too. + +4. Determine the normal Y feed increment (``upWeaveYFeeds``) + + You need to work out how much to feed the paper so that when the paper has moved by one head length in however many passes you have then each row space on the paper has been passed over by at least one nozzle. There will be one feed value for each pass and the feed values must comply with the following rules: + + .. code-block:: + + sum of feeds = passes * nozzles + feed%passes != 0 (feed is not exactly divisible by passes) + sum of (nozzles - feed) = 0 + + For example if ``passes=4`` and ``nozzles=15``, then sum of ``feeds=60``. The feed values could be ``1,1,1,57`` or ``15,15,15,15`` or ``14,15,18,13``. + + These values will be assigned to the ``upWeaveYFeeds`` parameter. + + You would need to experiment to see what combination looks best on the printer. + + I found it convenient to draw several lines of nozzles and then move them around to see how the different combinations would fill the paper. A computer drawing tool makes this easier than pencil and paper (I used Dia, a GNOME app). The number of nozzles would probably be be a good place to start. + + Remember that if the number of passes is more than 1 then the feed increment will be less than the nozzle spacing and passes × feed increment size must equal the physical distance between each nozzle. + +5. Determine the beginning of page pins (``upWeaveInitialPins``). + + These values will be assigned to the ``upWeaveInitialPins`` parameter and are the numbers of nozzles to operate in each of the initial passes at the top of a page. The nozzles that the values refer to are the topmost nozzles on the head, nearest the top margin. If the image doesn't start at the top margin then uniprint doesn't use these feeds. + + I don't know a mathematical relation for this except that at least one of the values must be the number of nozzles, but I'm sure that there must be one. I used a graphical method, the description that follows refers to the ascii diagram in below. + + Draw a line of nozzles for each pass arranged as they would be using the normal Y feed increment determined in step 3. In the diagram below this would be passes 5-8. + + Draw a line of nozzles that would print just before the first normal pass. The feed increment for this pass will be close to and most likely 1 or 2 units less than the feed increment of the last normal pass. In the example below this line is pass 4 and the feed increment is 13 whereas the normal feed increment is 15. + + Draw each pass before that with a small feed increment so that if all of the nozzles appearing above the first nozzle of the first normal pass operate then all of the spaces will be filled. This feed increment is usually 1 except in cases where some jiggery pokery is going on to make the printer print at an apparent higher resolution than the nozzle diameter. + + Now select the nozzles that will operate in each of theses initial passes so that the paper is filled. In each pass the nozzles must be adjacent to each other and at least one of the passes will have all the nozzles operating. I suspect that for each combination of normal Y feed increments there will only be one set of valid beginning of page increments. + + +Example: stc.upp from Aladdin Ghostscript 6.01 +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +15 nozzles spaced at 1/90 in, 360 dpi requires 4 passes. + + +.. code-block:: + + -dupWeaveYPasses=4 + -dupOutputPins=15 + -dupWeaveYFeeds="{15 15 15 15}" + -dupWeaveInitialYFeeds="{1 1 1 13}" + -dupWeaveInitialPins="{ 4 15 11 7}" + +The following diagram shows which nozzles operate during each pass. + +Passes 1-4 are beginning of page passes and passes 5-8 are normal passes. + + + +.. raw:: html + + <blockquote> + <p>x=nozzle operates, o=nozzle not used in this pass<tt></tt></p> + <p><tt> 1 2 3 4 5 6 7 8 - pass no</tt></p> + <br><tt>0 x</tt> + <br><tt>1 x</tt> + <br><tt>2 x</tt> + <br><tt>3 x</tt> + <br><tt>4 x</tt> + <br><tt>5 x</tt> + <br><tt>6 x</tt> + <br><tt>7 x</tt> + <br><tt>8 x</tt> + <br><tt>9 x</tt> + <br><tt>0 x</tt> + <br><tt>1 x</tt> + <br><tt>2 x</tt> + <br><tt>3 x</tt> + <br><tt>4 x</tt> + <br><tt>5 x</tt> + <br><tt>6 o x</tt> + <br><tt>7 x</tt> + <br><tt>8 x</tt> + <br><tt>9 x</tt> + <br><tt>0 o x</tt> + <br><tt>1 x</tt> + <br><tt>2 x</tt> + <br><tt>3 x</tt> + <br><tt>4 o x</tt> + <br><tt>5 x</tt> + <br><tt>6 x</tt> + <br><tt>7 x</tt> + <br><tt>8 o x</tt> + <br><tt>9 x</tt> + <br><tt>0 x</tt> + <br><tt>1 o x</tt> + <br><tt>2 o x</tt> + <br><tt>3 x</tt> + <br><tt>4 x</tt> + <br><tt>5 o x</tt> + <br><tt>6 o x</tt> + <br><tt>7 x</tt> + <br><tt>8 x</tt> + <br><tt>9 o x</tt> + <br><tt>0 o x</tt> + <br><tt>1 x</tt> + <br><tt>2 x</tt> + <br><tt>3 o x</tt> + <br><tt>4 o x</tt> + <br><tt>5 x</tt> + <br><tt>6 o + x</tt> + <br><tt>7 o x</tt> + <br><tt>8 o x</tt> + <br><tt>9 x</tt> + <br><tt>0 o + x</tt> + <br><tt>1 o x</tt> + <br><tt>2 o x</tt> + <br><tt>3 x</tt> + <br><tt>4 o + x</tt> + <br><tt>5 o x</tt> + <br><tt>6 o x</tt> + <br><tt>7 x</tt> + <br><tt>8 o + x</tt> + <br><tt>9 o x</tt> + <br><tt>0 x</tt> + <br><tt>1 + x</tt> + <br><tt>2 + x</tt> + <br><tt>3 x</tt> + <br><tt>4 x</tt> + <br><tt>5 + x</tt> + <br><tt>6 + x</tt> + <br><tt>7 x</tt> + <br><tt>8 x</tt> + <br><tt>9 + x</tt> + <br><tt>0 + x</tt> + <br><tt>1 x</tt> + <br><tt>2 x</tt> + <br><tt>3 + x</tt> + <br><tt>4 + x</tt> + <br><tt>5 x</tt> + <br><tt>6</tt> + <br><tt>7 + x</tt> + <br><tt>8 + x</tt> + <br><tt>9 x</tt> + <br><tt>0</tt> + <br><tt>1 + x</tt> + <br><tt>2 + x</tt> + <br><tt>3 x</tt> + <br><tt>4</tt> + <br><tt>5 + x</tt> + <br><tt>6 + x</tt> + <br><tt>7 x</tt> + <br><tt>8</tt> + <br><tt>9 + x</tt> + <br><tt>0 + x</tt> + <br><tt>1</tt> + <br><tt>2</tt> + <br><tt>3 + x</tt> + <br><tt>4 + x</tt> + <br><tt>5</tt> + <br><tt>6</tt> + <br><tt>7 + x</tt> + <br><tt>8 + x</tt> + <br><tt>9</tt> + <br><tt>0</tt> + <br><tt>1 + x</tt> + <br><tt>2 + x</tt> + <br><tt>3</tt> + <br><tt>4</tt> + <br><tt>5 + x</tt> + <br><tt>6</tt> + <br><tt>7</tt> + <br><tt>8</tt> + <br><tt>9 + x</tt> + <br><tt>0</tt> + <br><tt>1</tt> + <br><tt>2</tt> + <br><tt>3 + x</tt> + <br><tt>4</tt> + <br><tt>5</tt> + <br><tt>6</tt> + <br><tt>7 + x</tt> + </blockquote> + + +These parameters would also work: + + +.. code-block:: + + -dupWeaveYPasses=4 + -dupOutputPins=15 + -dupWeaveYFeeds="{14 15 18 13}" + -dupWeaveInitialYFeeds="{1 1 1 13}" + -dupWeaveInitialPins="{ 4 11 7 15}" + + +Extension to :title:`uniprint` for the Epson Stylus Color 300 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section was contributed by Glenn Ramsey. + +The Epson Stylus Color 300 uses a different command set to other Epson Stylus Color printers that use the ESC/P2 language. As far as I can tell its commands are a subset of ESC/P2. In ESC/P2 the colour to be printed is selected by a 'set colour' command and then the data sent is only printed in that colour until the colour is changed with another 'set colour' command. The Stylus Color 300 lacks this functionality. The data sent to the printer maps directly to the ink nozzles and colour of an output scan line in the printed output is determined by the position of the scan line within the data. This means that the driver must know how the nozzles are arranged and must format the output accordingly. The extension adds a format that I have called ``EscNozzleMap`` and adds some additional parameters to :title:`uniprint`. + + +- upOutputFormatselects the output method, and should be set to the value ``/EscNozzleMap`` to select this format. + + ``/EscNozzleMap`` + produces output for the Epson Stylus Color 300 + + + .. raw:: html + + <table width=100% border=1> + <tr> + <th colspan="3">uniprint parameters for the EscNozzleMap format</th> + </tr> + <tr> + <th align="Left">Parameter</th> + + <th align="Left">Type</th> + + <th align="Left">Use</th> + </tr> + <tr> + <td colspan="3"></td> + </tr> + <tr> + <td><code>upNozzleMapRowsPerPass</code></td> + + <td>Int + </td> + + + <td>output rows to generate for each pass of the head + </td> + </tr> + <tr> + <td><code>upNozzleMapPatternRepeat</code></td> + + <td>Int + </td> + + <td>no. of rows that correspond to the repeat pattern of the + nozzles + </td> + </tr> + <tr> + <td><code>upNozzleMapRowMask</code></td> + <td>Int[] + </td> + <td>mask indicating the colour of the nozzles + </td> + </tr> + <tr> + <td><code>upNozzleMapMaskScanOffset</code></td> + + <td>Int[] + </td> + <td>mask indicating the physical position of the nozzles + </td> + </tr> + </table> + + +**A more detailed description of the new parameters** + +``upNozzleMapRowsPerPass`` + The number of rows of data that are required to address all nozzles for a single pass of the head. There will always be this number of rows of output data generated. I'd expect it to be the same as the total number of nozzles but it wouldn't break the formatter if it wasn't. So if you wanted to print with only the 10th nozzle then row 10 would contain data corresponding to the bit pattern and all of the others would be padded with zeros. + +``upNozzleMapPatternRepeat`` + The number of nozzles in each repeated group on the printing head. This parameter must correspond with the length of the ``upNozzleMapRowMask`` array. + +``upNozzleMapRowMask`` + An array of integers that defines the colour of the nozzles on the head and whether the nozzles will be used to print. The array index defines the row index for the nozzle in the output data and the value defines the colour of the nozzle. The mapping of colours to values is defined in the table below. + + + .. list-table:: + header-rows: 1 + + + * - colour mask value + - + * - ``K`` + - 1 + * - ``C`` + - 2 + * - ``M`` + - 3 + * - ``Y`` + - 4 + * - ``no data`` + - 0 + + +A value of 0 means that the nozzle is not used and the row in the output data will be padded with zeros. + +``upNozzleMapMaskScanOffset`` + An array of integers that defines the physical position of the nozzles relative to the first nozzle in the repeated group. The relative distance is measured in printed line widths and will be different for different printing resolutions. This parameter is used because the physical spacing of the nozzles may not correspond to their mapping in the output data. For example the ESC300 has nozzles physically arranged something like this: + + + +.. raw:: html + + <table width=100% border=1> + <tr> + <td style="background-color: #00ffff !important;"> + </td> + <td style="background-color: #ffff00 !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: #ff00ff !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: #00ffff !important;"> + </td> + <td style="background-color: #ffff00 !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: #ff00ff !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: #ffffff !important;"> + </td> + </tr> + <tr> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: #00ffff !important;"> + </td> + <td style="background-color: #ffff00 !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: #ff00ff !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: #000000 !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;"> + </td> + <td style="background-color: #00ffff !important;"> + </td> + <td style="background-color: #ffff00 !important;"> + </td> + <td style="background-color: rgba(0,0,0,0) !important;">etc ... + </td> + </tr> + </table> + + +There is a one nozzle width space between the last two nozzles in each group. In the output data the data for the last nozzle in the group would be in row 5 (numbering starts at 0) but the nozzle is physically positioned at 6 spaces from the first nozzle. + + +Example 1 - Epson Stylus Color 300 - 360 dpi colour +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + + +.. code-block:: + + -dupWeaveYPasses=6 + -dupOutputPins=11 + -dupWeaveYFeeds="{ 11 11 11 11 11 11 }" + -dupWeaveInitialYFeeds="{ 1 1 1 1 1 7 }" + -dupWeaveInitialPins="{ 2 11 9 7 5 3 }" + -dupNozzleMapRowsPerPass=64 + -dupNozzleMapPatternRepeat=6 + -dupNozzleMapRowMask="{ 2 4 1 3 0 0 }" + -dupNozzleMapMaskScanOffset="{ 0 1 2 3 0 0 }" + + +The weaving parameters are the same as for any other :title:`uniprint` driver but they must be consistent with the nozzle map parameters. In this printer the coloured nozzles are spaced at 1/60" so 6 passes are required for 360 dpi resolution. + +In the example there are 64 rows of data required for each head pass. Each row must be completely filled with data for each pass so if certain nozzles do not print in the pass then the rows for those nozzles will be padded with zeroes. + +The row mask translates to "C Y K M 0 0" so in the output data rows 0,7,13,... will contain data for cyan, rows 1,8,14,... will contain data for yellow, etc. Rows 4,10,16,... and 5, 11,15,... will always be padded with zeroes. The ``upNozzleMapPatternRepeat`` parameter defines the length of the mask. + +The row mask is repeated for each group of ``upNozzleMapPatternRepeat`` rows in the output data. In this case there are 64 rows so there will be 10 groups of "C Y K M 0 0" followed by "C Y K M" which is equivalent to 11 output pins. + +The ``upNozzleMaskScanOffset`` array indicates how the data from the scan buffer is mapped to the output data. The data is presented to the formatter as a buffer of four colour scanlines. The index of the scanline being printed, lets call it y, always corresponds, in this example, to the physical position of the cyan nozzle but since the nozzles are not on the same horizontal line then the other colours for the current pass must come from other scanlines in the scan buffer. The example is { 0 1 2 3 0 0 }, this means that when printing a 4 colour image the magenta data would come from scanline y+3, the black from scanline y+2, etc. It would have been possible in this case to use the array index instead of the ``upNozzleMaskScanOffset`` parameter however the parameter is necessary to be able to use the full capability of the printer in black only mode. + + + +Example 2 - Epson Stylus Color 300 - 180 dpi black only +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. code-block:: + + -dupMargins="{ 9.0 39.96 9.0 9.0}" + -dupWeaveYPasses=1 + -dupOutputPins=31 + -dupNozzleMapRowsPerPass=64 + -dupNozzleMapPatternRepeat=6 + -dupNozzleMapRowMask="{ 0 0 1 0 1 1}" + -dupNozzleMapMaskScanOffset="{ 0 0 0 0 1 2 }" + + +In this example there is no weaving. + +The ESC300 has black nozzles evenly physically arranged as ``K K K`` but the data must be sent to the printer as ``00K0KK``. This is handled by the ``upNozzleMapRowMask`` and ``upNozzleMaskScanOffset`` arrays. The ``upNozzleMapRowMask`` array is ``{ 0 0 1 0 1 1}`` which translates to ``{ 0 0 K 0 K K }`` so rows 0, 1 and 3 will always contain zeros and the other rows will contain data. + +The ``upNozzleMaskScanOffset`` array in this case is ``{ 0 0 0 0 1 2 }`` so if the data for the 1st nozzle comes from row y in the scan buffer then the data for the 2nd and 3rd nozzles will come from rows y+1 and y+2. + + +Example 3 - Epson Stylus Color 300 - 360 dpi black only +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. code-block:: + + -dupWeaveYPasses=2 + -dupOutputPins=31 + -dupWeaveYFeeds="{31 31}" + -dupWeaveInitialYFeeds="{1 31}" + -dupWeaveInitialPins="{16 31}" + -dupNozzleMapRowsPerPass=64 + -dupNozzleMapPatternRepeat=6 + -dupNozzleMapRowMask="{ 0 0 1 0 1 1}" + -dupNozzleMapMaskScanOffset="{ 0 0 0 0 2 4 }" + +In this example 2 weave passes are required to achieve the desired resolution. + +The ``upNozzleMaskScanOffset`` array in this case is ``{ 0 0 0 0 2 4 }`` because there are two weave passes so if the data for the first nozzle comes from row y in the scan buffer then the data for the 2nd and 3rd nozzles must come from rows ``y+(1*2)`` and ``y+(2*2)``. + + +Glenn Ramsey + +glennr at users.sourceforge.net + +February 2001 + + +.. External links + +.. _Uli Wortmann: uliw@erdw.ethz.ch +.. _Martin Gerbershagen: ger@ulm.temic.de +.. _Matthew Gelhaus: hp880@gelhaus.net +.. _gelhaus.net/hp880c: http://www.gelhaus.net/hp880c/ +.. _Stephan C. Buchert: scb@stelab.nagoya-u.ac.jp +.. _Yoshio Kuniyoshi: yoshio@nak.math.keio.ac.jp + +.. _David Gaudine: david@donald.concordia.ca +.. _Robert M. Kenney: rmk@unh.edu +.. _James McPherson: someone@erols.com +.. _Ian Thurlbeck: ian@stams.strath.ac.uk +.. _Klaus-Gunther Hess: ghess@elmos.de +.. _Gunther Hess: ghess@elmos.de + +.. _Jason Patterson: jason@reflections.com.au +.. _Michael Lossin: losse@germanymail.com + +.. _L. Peter Deutsch: https://en.wikipedia.org/wiki/L._Peter_Deutsch + +.. include:: footer.rst
\ No newline at end of file diff --git a/doc/src/Use.rst b/doc/src/Use.rst new file mode 100644 index 00000000..e8aaf5e4 --- /dev/null +++ b/doc/src/Use.rst @@ -0,0 +1,3163 @@ +.. title:: Using Ghostscript + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _Use.htm: + + +Using Ghostscript +=================================== + + +This document describes how to use the command line Ghostscript client. Ghostscript is also used as a general engine inside other applications (for viewing files for example). Please refer to the documentation for those applications for using Ghostscript in other contexts. + + +Invoking Ghostscript +------------------------------------------ + + +The command line to invoke Ghostscript is essentially the same on all systems, although the name of the executable program itself may differ among systems. For instance, to invoke Ghostscript on unix-like systems type: + +.. code-block:: bash + + gs [options] {filename 1} ... [options] {filename N} ... + +Here are some basic examples. The details of how these work are described below. + +To view a file: + +.. code-block:: bash + + gs -dSAFER -dBATCH document.pdf + + +You'll be prompted to press return between pages. + +To convert a figure to an image file: + +.. code-block:: bash + + gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -dGraphicsAlphaBits=4 \ + -sOutputFile=tiger.png tiger.eps + +To render the same image at 300 dpi: + +.. code-block:: bash + + gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r300 \ + -sOutputFile=tiger_300.png tiger.eps + + +To render a figure in grayscale: + + +.. code-block:: bash + + + gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pnggray -sOutputFile=figure.png figure.pdf + + +To rasterize a whole document: + +.. code-block:: bash + + gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pgmraw -r150 \ + -dTextAlphaBits=4 -sOutputFile='paper-%00d.pgm' paper.ps + + +There are also a number of utility scripts for common to convert a PostScript document to PDF: + + +.. code-block:: bash + + ps2pdf file.ps + + +The output is saved as ``file.pdf``. + + +There are other utility scripts besides ``ps2pdf``, including ``pdf2ps``, ``ps2epsi``, ``pdf2dsc``, ``ps2ascii``, ``ps2ps`` and ``ps2ps2``. These just call Ghostscript with the appropriate (if complicated) set of options. You can use the 'ps2' set with eps files. + +Ghostscript is capable of interpreting PostScript, encapsulated PostScript (EPS), DOS EPS (EPSF), and Adobe Portable Document Format (PDF). The interpreter reads and executes the files in sequence, using the method described under "`File searching`_" to find them. + +The interpreter runs in interactive mode by default. After processing the files given on the command line (if any) it reads further lines of PostScript language commands from the primary input stream, normally the keyboard, interpreting each line separately. To quit the interpreter, type "``quit``". The ``-dBATCH -dNOPAUSE`` options in the examples above disable the interactive prompting. The interpreter also quits gracefully if it encounters end-of-file or control-C. + +The interpreter recognizes many options. An option may appear anywhere in the command line, and applies to all files named after it on the line. Many of them include "=" followed by a parameter. The most important are described in detail here. Please see the reference sections on `Command line options`_ and `Devices <Devices.htm>`_ for a more complete listing. + + + +Help at the command line: gs -h +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can get a brief help message by invoking Ghostscript with the ``-h`` or ``-?`` switch, like this: + + +.. code-block:: bash + + gs -h + gs -? + + +The message shows for that version of the Ghostscript executable: + +- the version and release information. +- the general format of the command line. +- a few of the most useful options. +- the formats it can interpret. +- the available output devices. +- the search path. +- the bug report address. + + +On other systems the executable may have a different name: + + + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - System + - Invocation Name + * - Unix + - gs + * - VMS + - gs + * - MS Windows 95 and later + - gswin32.exe + + gswin32c.exe + + gswin64.exe + + gswin64c.exe + + * - OS/2 + - gsos2 + + +On Windows, the two digit number indicates the word length of the system for which the binary was built (so ``gswin32.exe`` is for x86 Windows systems, whilst ``gswin64.exe`` is for x86_64 Windows systems). And the "c" suffix indicates a Windows console based binary (note that the "display device" window will still appear). + + + + +Selecting an output device +------------------------------------------ + + + +Ghostscript has a notion of 'output devices' which handle saving or displaying the results in a particular format. Ghostscript comes with a diverse variety of such devices supporting vector and raster file output, screen display, driving various printers and communicating with other applications. + +The command line option ``'-sDEVICE=device'`` selects which output device Ghostscript should use. If this option isn't given the default device (usually a display device) is used. Ghostscript's built-in help message (``gs -h``) lists the available output devices. For complete description of the devices distributed with Ghostscript and their options, please see the `Devices <Devices.htm>`_ section of the documentation. + +Note that this switch must precede the name of the first input file, and only its first use has any effect. For example, for printer output in a configuration that includes an Epson printer driver, instead of just ``'gs myfile.ps'`` you might use: + + +.. code-block:: bash + + gs -sDEVICE=epson myfile.ps + + + + + +The output device can also be set through the ``GS_DEVICE`` environment variable. + +Once you invoke Ghostscript you can also find out what devices are available by typing ``'devicenames =='`` at the interactive prompt. You can set the output device and process a file from the interactive prompt as well: + +.. code-block:: bash + + (epson) selectdevice + (myfile.ps) run + +All output then goes to the Epson printer instead of the display until you do something to change devices. You can switch devices at any time by using the ``selectdevice`` procedure, for instance like one of these: + +.. code-block:: bash + + (x11alpha) selectdevice + (epson) selectdevice + + + +Output resolution +~~~~~~~~~~~~~~~~~~~ + +Some printers can print at several different resolutions, letting you balance resolution against printing speed. To select the resolution on such a printer, use the ``-r`` switch: + + +.. code-block:: bash + + gs -sDEVICE=printer -rXRESxYRES + + +where ``XRES`` and ``YRES`` are the requested number of dots (or pixels) per inch. Where the two resolutions are same, as is the common case, you can simply use ``-rres``. + +The ``-r`` option is also useful for controlling the density of pixels when rasterizing to an image file. It is used this way in the examples at the beginning of this document. + + +Output to files +~~~~~~~~~~~~~~~~ + +Ghostscript 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 printer. + +To send the output to a file, use the ``-sOutputFile=`` switch or the :ref:`-o switch <O switch>` (below). For instance, to direct all output into the file ``ABC.xyz``, use: + +.. code-block:: bash + + gs -sOutputFile=ABC.xyz + + +When printing on MS Windows systems, output normally goes directly to the printer, ``PRN``. On Unix and VMS systems it normally goes to a temporary file which is sent to the printer in a separate step. When using Ghostscript 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. + +Ghostscript also accepts the special filename '``-``' which indicates the output should be written to standard 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: + + +.. code-block:: bash + + gs -sOutputFile=%os%%abc + + +Please see `Ghostscript and the PostScript Language <Language.htm>`_ and the PostScript Language Reference Manual for more details on ``%`` and filedevices. + + +.. note:: + + On MS Windows systems, the ``%`` character also has a special meaning for the command processor (shell), so you will have to double it, e.g.: + + .. code-block:: bash + + gs -sOutputFile=%%os%%%%abc + + +Note, some devices (e.g. :title:`pdfwrite`, :title:`ps2write`) only write the output file upon exit, but changing the OutputFile device parameter will cause these devices to emit the pages received up to that point and then open the new file name given by OutputFile. + +For example, in order to create two PDF files from a single invocation of Ghostscript the following can be used: + +.. code-block:: bash + + gs -sDEVICE=pdfwrite -o tiger.pdf examples/tiger.eps -c "<< /OutputFile (colorcir.pdf) >> setpagedevice" -f examples/colorcir.ps + + + +.. _Use_OnePagePerFile: + + +One page per file +"""""""""""""""""""" + + +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 Ghostscript to put each page of output in a series of similarly named files. To do this place a template ``'%d'`` in the filename which Ghostscript will replace with the page number. + +Note: Since the % character is used to precede the page number format specification, in order to represent a file name that contains a %, double % characters must be used. For example for the file ``my%foo`` the OutputFile string needs to be ``my%%foo``. + +The format can in fact be more involved than a simple ``'%d'``. The format specifier is of a form similar to the C ``printf`` format. The general form supported is: + +.. code-block:: bash + + %[flags][width][.precision][l]type + + where: flags is one of: #+- + type is one of: diuoxX + + +For more information, please refer to documentation on the C printf format specifications. Some examples are: + +.. code-block:: bash + + -sOutputFile=ABC-%d.png + produces 'ABC-1.png', ... , 'ABC-10.png', .. + -sOutputFile=ABC-%03d.pgm + produces 'ABC-001.pgm', ... , 'ABC-010.pgm', ... + -sOutputFile=ABC_p%04d.tiff + produces 'ABC_p0001.tiff', ... , 'ABC_p0510.tiff', ... , 'ABC_p5238.tiff' + + +Note, however that the one page per file feature may not supported by all devices. Also, since some devices write output files when opened, there may be an extra blank page written (:title:`pdfwrite`, :title:`ps2write`, :title:`eps2write`, :title:`pxlmono`, :title:`pxlcolor`). + +As noted above, when using MS Windows console (command.com or cmd.exe), you will have to double the ``%`` character since the ``%`` is used by that shell to prefix variables for substitution, e.g., + + +.. code-block:: bash + + gswin32c -sOutputFile=ABC%%03d.xyz + + + +.. _O switch: + +-o option +"""""""""""""""""" + +As a convenient shorthand you can use the ``-o`` option followed by the output file specification as discussed above. The ``-o`` option also sets the :ref:`-dBATCH and -dNOPAUSE options<Interaction related parameters>`. This is intended to be a quick way to invoke Ghostscript to convert one or more input files. + +For instance, to convert somefile.ps to JPEG image files, one per page, use: + + +.. code-block:: bash + + gs -sDEVICE=jpeg -o out-%d.jpg somefile.ps + +is equivalent to: + +.. code-block:: bash + + gs -sDEVICE=jpeg -sOutputFile=out-%d.jpg -dBATCH -dNOPAUSE somefile.ps + + +.. _Use_PaperSize: + + +Choosing paper size +~~~~~~~~~~~~~~~~~~~~~~~ + + +Ghostscript is distributed configured to use U.S. letter paper as its default page size. There are two ways to select other paper sizes from the command line: + +If the desired paper size is listed in the section on paper sizes known to Ghostscript below, you can select it as the default paper size for a single invocation of Ghostscript by using the ``-sPAPERSIZE=`` switch, for instance: + +.. code-block:: bash + + -sPAPERSIZE=a4 + -sPAPERSIZE=legal + +Otherwise you can set the page size using the pair of switches: + +.. code-block:: bash + + -dDEVICEWIDTHPOINTS=w -dDEVICEHEIGHTPOINTS=h + + +Where ``w`` be the desired paper width and ``h`` be the desired paper height in points (units of 1/72 of an inch). + + +Individual documents can (and often do) specify a paper size, which takes precedence over the default size. To force a specific paper size and ignore the paper size specified in the document, select a paper size as just described, and also include the :ref:`-dFIXEDMEDIA switch<FIXEDMEDIA>` on the command line. + +The default set of paper sizes will be included in the ``currentpagedevice`` in the ``InputAttributes`` dictionary with each paper size as one of the entries. The last entry in the dictionary (which has numeric keys) is a non-standard (Ghostscript extension) type of PageSize where the array has four elements rather than the standard two elements. This four element array represents a page size range where the first two elements are the lower bound of the range and the second two are the upper bound. By default these are [0, 0] for the lower bound and [16#fffff, 16#fffff] for the upper bound. + +The range type of PageSize is intended to allow flexible page size sepcification for non-printer file formats such as JPEG, PNG, TIFF, EPS, ... + +For actual printers, either the entire ``InputAttributes`` dictionary should be replaced or the range type entry should not be included. To simplify using the default page sizes in the ``InputAttributes`` dictionary, the command line option ``-dNORANGEPAGESIZE`` can be used. Using this option will result in automatic rotation of the document page if the requested page size matches one of the default page sizes. + +When the :ref:`-dFIXEDMEDIA switch<FIXEDMEDIA>` is given on the command line, the ``InputAttributes`` dictionary will only be populated with the single page size. This allows the ``-dPSFitPage`` option to fit the page size requested in a PostScript file to be rotated, scaled and centered for the best fit on the specified page. + + + +Changing the installed default paper size +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +You can change the installed default paper size on an installed version of Ghostscript, by editing the initialization file ``gs_init.ps``. This file is usually in the ``Resource/Init`` directory somewhere in the search path. See the section on :ref:`finding files<Use_How Ghostscript finds files>` for details. + +Find the line: + +.. code-block:: bash + + % /DEFAULTPAPERSIZE (a4) def + +Then to make A4 the default paper size, uncomment the line to change this to: + +.. code-block:: bash + + /DEFAULTPAPERSIZE (a4) def + +For a4 you can substitute any :ref:`paper size Ghostscript knows<Known Paper Sizes>`. + +This supecedes the previous method of uncommenting the line ``% (a4) ...``. + +Sometimes the initialization files are compiled into Ghostscript and cannot be changed. + +On Windows and some Linux builds, the default paper size will be selected to be a4 or letter depending on the locale. + + + + +.. _Pipes: + +Interacting with pipes +----------------------------- + + + +As noted above, input files are normally specified on the command line. However, one can also "pipe" input into Ghostscript from another program by using the special file name '``-``' which is interpreted as standard input. Examples: + + +.. code-block:: bash + + {some program producing ps} | gs [options] - + zcat paper.ps.gz | gs - + + +When Ghostscript finishes reading from the pipe, it quits rather than going into interactive mode. Because of this, options and files after the '``-``' in the command line will be ignored. + +On Unix and MS Windows systems you can send output to a pipe in the same way. For example, to pipe the output to ``lpr``, use the command: + + +.. code-block:: bash + + gs -q -sOutputFile=- | lpr + +In this case you must also use the ``-q`` switch to prevent Ghostscript from writing messages to standard output which become mixed with the intended output stream. + +Also, using the ``-sstdout=%stderr`` option is useful, particularly with input from PostScript files that may print to stdout. + +Similar results can be obtained with the ``%stdout`` and ``%pipe%`` filedevices. The example above would become: + + +.. code-block:: bash + + gs -sOutputFile=%stdout -q | lpr + +or: + +.. code-block:: bash + + gs -sOutputFile=%pipe%lpr + + +(again, doubling the ``%`` character on MS Windows systems.) + +In the last case, ``-q`` isn't necessary since Ghostscript handles the pipe itself and messages sent to stdout will be printed as normal. + + + +Using Ghostscript with PDF files +---------------------------------------------------------- + + +Ghostscript is normally built to interpret both PostScript and PDF files, examining each file to determine automatically whether its contents are PDF or PostScript. All the normal switches and procedures for interpreting PostScript files also apply to PDF files, with a few exceptions. In addition, the ``pdf2ps`` utility uses Ghostscript to convert PDF to (Level 2) PostScript. + + +Switches for PDF files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here are some command line options specific to PDF: + +``-dNEWPDF`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +From release 9.55.0 Ghostscript incorporates two complete PDF interpreters; the original long-standing interpreter is written in PostScript but there is now a new interpreter written in C. +At present the old PostScript-based interpreter remains the default, in future releases the new C-based interpreter will become the default, though we would encourage people to experiment with the new interpreter and send us feedback. While there are two interpreters the command-line switch NEWPDF will allow selection of the existing interpreter when false and the new interpreter when true. + +``-dPDFINFO`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Starting with release 9.56.0 this new switch will work with the PDF interpreter (GhostPDF) and with the PDF interpreter integrated into Ghostscript. When this switch is set the interpreter will emit information regarding the file, similar to that produced by the old pdf_info.ps program in the 'lib' folder. +The format is not entirely the same, and the search for fonts and spot colours is 'deeper' than the old program; pdf_info.ps stops at the page level whereas the PDFINFO switch will descend into objects such as Forms, Images, type 3 fonts and Patterns. In addition different instances of fonts with the same name are now enumerated. + +Unlike the pdf_info.ps program there is no need to add the input file to the list of permitted files for reading (using --permit-file-read). + +``-dPDFFitPage`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Rather than selecting a PageSize given by the PDF MediaBox, BleedBox (see -``dUseBleedBox``), TrimBox (see ``-dUseTrimBox``), ArtBox (see ``-dUseArtBox``), or CropBox (see ``-dUseCropBox``), the PDF file will be scaled to fit the current device page size (usually the default page size). +This is useful for creating fixed size images of PDF files that may have a variety of page sizes, for example thumbnail images. + +This option is also set by the ``-dFitPage`` option. + + +``-dPrinted`` & ``-dPrinted=false`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Determines whether the file should be displayed or printed using the "screen" or "printer" options for annotations and images. With ``-dPrinted``, the output will use the file's "print" options; with ``-dPrinted=false``, the output will use the file's "screen" options. If neither of these is specified, the output will use the screen options for any output device that doesn't have an ``OutputFile`` parameter, and the printer options for devices that do have this parameter. + +``-dUseBleedBox`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the page size to the BleedBox rather than the MediaBox. defines the region to which the contents of the page should be clipped when output in a production environment. This may include any extra bleed area needed to accommodate the physical limitations of cutting, folding, and trimming equipment. The actual printed page may include printing marks that fall outside the bleed box. + +``-dUseTrimBox`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the page size to the TrimBox rather than the MediaBox. The trim box defines the intended dimensions of the finished page after trimming. Some files have a TrimBox that is smaller than the MediaBox and may include white space, registration or cutting marks outside the CropBox. Using this option simulates appearance of the finished printed page. + +``-dUseArtBox`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the page size to the ArtBox rather than the MediaBox. The art box defines the extent of the page's meaningful content (including potential white space) as intended by the page's creator. The art box is likely to be the smallest box. It can be useful when one wants to crop the page as much as possible without losing the content. + +``-dUseCropBox`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the page size to the CropBox rather than the MediaBox. Unlike the other "page boundary" boxes, CropBox does not have a defined meaning, it simply provides a rectangle to which the page contents will be clipped (cropped). By convention, it is often, but not exclusively, used to aid the positioning of content on the (usually larger, in these cases) media. + +``-sPDFPassword=password`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Sets the user or owner password to be used in decoding encrypted PDF files. For files created with encryption method 4 or earlier, the password is an arbitrary string of bytes; with encryption method 5 or later, it should be text in either UTF-8 or your locale's character set (Ghostscript tries both). + + +``-dShowAnnots=false`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Don't enumerate annotations associated with the page ``Annots`` key. Annotations are shown by default. + +In addition, finer control is available by defining an array ``/ShowAnnotTypes``. Annotation types listed in this array will be drawn, whilst those not listed will not be drawn. + +To use this feature: ``-c "/ShowAnnotTypes [....] def" -f <input file>`` + +Where the array can contain one or more of the following names: ``/Stamp``, ``/Squiggly``, ``/Underline``, ``/Link``, ``/Text``, ``/Highlight``, ``/Ink``, ``/FreeText``, ``/StrikeOut`` and ``/stamp_dict``. + +For example, adding the follow to the command line: ``-c "/ShowAnnotTypes [/Text /UnderLine] def" -f <input file>`` would draw only annotations with the subtypes "Text" and "UnderLine". + +``-dShowAcroForm=false`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Don't show annotations from the Interactive Form Dictionary (AcroForm dictionary). By default, AcroForm processing is now enabled because Adobe Acrobat does this. This option is provided to restore the previous behavior which corresponded to older Acrobat. + +``-dNoUserUnit`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Ignore ``UserUnit`` parameter. This may be useful for backward compatibility with old versions of Ghostscript and Adobe Acrobat, or for processing files with large values of ``UserUnit`` that otherwise exceed implementation limits. + +``-dRENDERTTNOTDEF`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +If a glyph is not present in a font the normal behaviour is to use the /.notdef glyph instead. On TrueType fonts, this is often a hollow sqaure. Under some conditions Acrobat does not do this, instead leaving a gap equivalent to the width of the missing glyph, or the width of the /.notdef glyph if no /Widths array is present. Ghostscript now attempts to mimic this undocumented feature using a user parameter ``RenderTTNotdef``. The PDF interpreter sets this user parameter to the value of ``RENDERTTNOTDEF`` in systemdict, when rendering PDF files. To restore rendering of /.notdef glyphs from TrueType fonts in PDF files, set this parameter to true. + + +These command line options are no longer specific to PDF, but have some specific differences with PDF files: + + +``-dFirstPage=pagenumber`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Begin on the designated page of the document. Pages of all documents in PDF collections are numbered sequentionally. + + +``-dLastPage=pagenumber`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Stop after the designated page of the document. Pages of all documents in PDF collections are numbered sequentionally. + + +.. note:: + + The PDF and XPS interpreters allow the use of a ``-dLastPage`` less than ``-dFirstPage``. In this case the pages will be processed backwards from LastPage to FirstPage. + + + +``-sPageList=pageranges`` +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Page ranges are separated by a comma '`,`'. Each range of pages can consist of: + +- (a) a single page number. +- (b) a range with a starting page number, followed by a dash '`-`' followed by an ending page number. +- (c) a range with a starting page number, followed by a dash '`-`' which ends at the last page. +- (d) the keyword "even" or "odd", which optionally can be followed by a colon ':' and a page range. If there is no page range then all even or odd pages are processed in forward order. +- (e) a range with an initial dash '`-`' followed by and ending page number which starts at the last page and ends at the specified page (PDF and XPS only). + +For example: + + +.. code-block:: bash + + -sPageList=1,3,5 indicates that pages 1, 3 and 5 should be processed. + -sPageList=5-10 indicates that pages 5, 6, 7, 8, 9 and 10 should be processed. + -sPageList=1,5-10,12- indicates that pages 1, 5, 6, 7, 8, 9, 10 and 12 onwards should be processed. + -sPageList=odd:3-7,9-,-1,8 processes pages 3, 5, 7, 9, 10, 11, ..., last, last, last-1, ..., 1, 8 + + +.. note:: + + Use of ``PageList`` overrides ``FirstPage`` and/or ``LastPage``, if you set these as well as ``PageList`` they will be ignored. + + +Be aware that using the ``%d`` syntax for ``-sOutputFile=...`` does not reflect the page number in the original document. If you chose (for example) to process even pages by using ``-sPageList=even``, then the output of ``-sOutputFile=out%d.png`` would still be ``out1.png``, ``out2.png``, ``out3.png`` etc. + +For PostScript or PCL input files, the list of pages must be given in increasing order, you cannot process pages out of order or repeat pages and this will generate an error. PCL and PostScript require that all the pages must be interpreted, however since only the requested pages are rendered, this can still lead to savings in time. + +The PDF and XPS interpreters handle this in a slightly different way. Because these file types provide for random access to individual pages in the document these inerpreters only need to process the required pages, and can do so in any order. + +Because the PostScript and PCL interpreters cannot determine when a document terminates, sending multple files as input on the command line does not reset the ``PageList`` between each document, each page in the second and subsequent documents is treated as following on directly from the last page in the first document. The PDF interpreter, however, does not work this way. Since it knows about individual PDF files the ``PageList`` is applied to each PDF file separately. So if you were to set ``-sPageList=1,2`` and then send two PDF files, the result would be pages 1 and 2 from the first file, and then pages 1 and 2 from the second file. The PostScript interpreter, by contrast, would only render pages 1 and 2 from the first file. This means you must exercise caution when using this switch, and probably should not use it at all when processing a mixture of PostScript and PDF files on the same command line. + + + +Problems interpreting a PDF file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Occasionally you may try to read or print a 'PDF' file that Ghostscript doesn't recognize as PDF, even though the same file can be opened and interpreted by an Adobe Acrobat viewer. In many cases, this is because of incorrectly generated PDF. Acrobat tends to be very forgiving of invalid PDF files. Ghostscript tends to expect files to conform to the standard. For example, even though valid PDF files must begin with %PDF, Acrobat will scan the first 1000 bytes or so for this string, and ignore any preceding garbage. + +In the past, Ghostscript's policy has been to simply fail with an error message when confronted with these files. This policy has, no doubt, encouraged PDF generators to be more careful. However, we now recognize that this behavior is not very friendly for people who just want to use Ghostscript to view or print PDF files. Our new policy is to try to render broken PDF's, and also to print a warning, so that Ghostscript is still useful as a sanity-check for invalid files. + + + +PDF files from standard input +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PDF language, unlike the PostScript language, inherently requires random access to the file. If you provide PDF to standard input using the special filename :ref:`'-'<Pipes>`, Ghostscript will copy it to a temporary file before interpreting the PDF. + + + + + +Using Ghostscript with EPS files +---------------------------------------------------------- + +Encapsulated PostScript (EPS) files are intended to be incorporated in other PostScript documents and may not display or print on their own. An EPS file must conform to the Document Structuring Conventions, must include a ``%%BoundingBox`` line to indicate the rectangle in which it will draw, must not use PostScript commands which will interfere with the document importing the EPS, and can have either zero pages or one page. Ghostscript has support for handling EPS files, but requires that the ``%%BoundingBox`` be in the header, not the trailer. To customize EPS handling, see :ref:`EPS parameters<EPS parameters>`. + +For the official description of the EPS file format, please refer to the Adobe documentation. + + +Using Ghostscript with overprinting and spot colors +---------------------------------------------------------- + +In general with PostScript and PDF interpreters, the handling of overprinting and spot colors depends upon the process color model of the :ref:`output device<Selecting an output device>`. Devices that produce gray or RGB output have an additive process color model. Devices which produce CMYK output have a subtractive process color model. Devices may, or may not, have support for spot colors. + +.. note:: + + The differences in appearance of files with overprinting and spot colors caused by the differences in the color model of the output device are part of the PostScript and PDF specifications. They are not due to a limitation in the implementation of Ghostscript or its output devices. + + +With devices which use a subtractive process color model, both PostScript and PDF allow the drawing of objects using colorants (inks) for one or more planes without affecting the data for the remaining colorants. Thus the inks for one object may overprint the inks for another object. In some cases this produces a transparency like effect. (The effects of overprinting should not be confused with the PDF 1.4 blending operations which are supported for all output devices.) Overprinting is not allowed for devices with an additive process color model. With files that use overprinting, the appearance of the resulting image can differ between devices which produce RGB output versus devices which produce CMYK output. Ghostscript automatically overprints (if needed) when the output device uses a subtractive process color model. For example, if the file is using overprinting, differences can be seen in the appearance of the output from the :ref:`tiff24nc and tiff32nc devices<Devices_TIFF>` which use an RGB and a CMYK process color models. + +Most of the Ghostscript :ref:`output devices<Devices.htm>` do not have file formats which support spot colors. Instead spot colors are converted using the tint transform function contained within the color space definition.. However there are several devices which have support for spot colors. The PSD format (Adobe Photoshop) produced by the :ref:`psdcmyk device<Devices_PSD>` contains both the raster data plus an equivalent CMYK color for each spot color. This allows Photoshop to simulate the appearance of the spot colors. The :ref:`display device (MS Windows, OS/2, gtk+)<Devices_Display_Device>` can be used with different color models: Gray, RGB, CMYK only, or CMYK plus spot colors (separation). The display device, when using its CMYK plus spot color (separation) mode, also uses an equivalent CMYK color to simulate the appearance of the spot color. The :ref:`tiffsep device<Devices_TIFF>` creates output files for each separation (CMYK and any spot colors present). It also creates a composite CMYK file using an equivalent CMYK color to simulate the appearance of spot colors. The :ref:`xcfcmyk device<Devices_XCF>` creates output files with spot colors placed in separate alpha channels. (The XCF file format does not currently directly support spot colors.) + +Overprinting with spot colors is not allowed if the tint transform function is being used to convert spot colors. Thus if spot colors are used with overprinting, then the appearance of the result can differ between output devices. One result would be obtained with a CMYK only device and another would be obtained with a CMYK plus spot color device. In a worst case situation where a file has overprinting with both process (CMYK) and spot colors, it is possible to get three different appearances for the same input file using the :ref:`tiff24nc<Devices_TIFF>` (RGB), :ref:`tiff32nc<Devices_TIFF>` (CMYK), and :ref:`tiffsep<Devices_TIFF>` (CMYK plus spot colors) devices. + + +.. note:: + In Adobe Acrobat, viewing of the effects of overprinting is enabled by the 'Overprint Preview' item in the 'Advanced' menu. This feature is not available in the free Acrobat Reader. The free Acrobat Reader also uses the tint transform functions to convert spot colors to the appropriate alternate color space. + + + +.. _Use_How Ghostscript finds files: + +How Ghostscript finds files +---------------------------------------------------------- + + +When looking for initialization files (``gs_*.ps``, ``pdf_*.ps``), font files, the ``Fontmap`` file, files named on the command line, and resource files, Ghostscript first tests whether the file name specifies an absolute path. + + + +Testing a file name for an absolute path +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - System + - Does the name ... + * - Unix + - Begin with ``/`` ? + * - MS Windows + - Have ``:`` as its second character, or begin with ``/``, ``\``, or ``//servername/share/`` ? + * - VMS + - Contain a node, device, or root specification? + + +If the test succeeds, Ghostscript tries to open the file using the name given. Otherwise it tries directories in this order: + +#. The current directory if enabled by the :ref:`-P switch<P switch>`. +#. The directories specified by :ref:`-I switches<I switch>` in the command line, if any. +#. The directories specified by the ``GS_LIB`` environment variable, if any. +#. If built with ``COMPILE_INITS=1`` (currently the default build) the files in the ``%rom%Resource/`` and ``%rom%iccprofiles/`` directories are built into the executable. +#. The directories specified by the ``GS_LIB_DEFAULT`` macro (if any) in the makefile when this executable was built. + + +``GS_LIB_DEFAULT``, ``GS_LIB``, and the ``-I`` parameter may specify either a single directory or a list of directories separated by a character appropriate for the operating system ("``:``" on Unix systems, "``,``" on VMS systems, and "``;``" on MS Windows systems). By default, Ghostscript no longer searches the current directory first but provides ``-P`` switch for a degree of backward compatibility. + +Note that Ghostscript does not use this file searching algorithm for the ``run`` or ``file`` operators: for these operators, it simply opens the file with the name given. To run a file using the searching algorithm, use ``runlibfile`` instead of ``run``. + + + +.. _PS resources: + +Finding PostScript Level 2 resources +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Adobe specifies that resources are installed in a single directory. Ghostscript instead maintains a list of resource directories, and uses an extended method for finding resource files. + +The search for a resource file depends on whether the value of the system parameter ``GenericResourceDir`` specifies an absolute path. The user may set it as explained in :ref:`resource related parameters<resource related parameters>`. + +If the user doesn't set the system parameter ``GenericResourceDir``, or use the ``-sGenericResourceDir=`` command line option, Ghostscript creates a default value for it by looking on the directory paths explained in `How Ghostscript finds files`_, excluding the current directory. The first path with Resource in it is used, including any prefix up to the path separator character following the string Resource. For example, when ``COMPILE_INITS=1`` (the current default build), if the first path is ``%rom%Resource/Init/``, then the ``GenericResourceDir`` systemparam will be set to ``%rom%Resource/`` by default. + +If the value of the system parameter ``GenericResourceDir`` is an absolute path (the default), Ghostscript assumes a single resource directory. It concatenates: + + +#. The value of the system parameter ``GenericResourceDir``. +#. The name of the resource category (for instance, ``CMap``). +#. The name of the resource instance (for instance, ``Identity-H``). + +If the value of the system parameter GenericResourceDir is not an absolute path, Ghostscript assumes multiple resource directories. In this case it concatenates: + +#. A directory listed in the section `How Ghostscript finds files`_, except the current directory. +#. The value of the system parameter ``GenericResourceDir``. +#. The name of the resource category (for instance, ``CMap``). +#. The name of the resource instance (for instance, ``Identity-H``). + + +Due to possible variety of the part 1, the first successful combination is used. For example, if the value of the system parameter ``GenericResourceDir`` is the string ``../Resource/`` (or its equivalent in the file path syntax of the underlying platform), Ghostscript searches for ``../Resource/CMap/Identity-H`` from all directories listed in `How Ghostscript finds files`_. So in this example, if the user on a Windows platform specifies the command line option ``-I.;../gs/lib;c:/gs8.50/lib``, Ghostscript searches for ``../gs/Resource/CMap/Identity-H`` and then for ``c:/gs8.50/Resource/CMap/Identity-H``. + +To get a proper platform dependent syntax Ghostscript inserts the value of the system parameter ``GenericResourcePathSep`` (initially "``/``" on Unix and Windows, "``:``" on MacOS, "``.``" or "``]``" on OpenVMS). The string ``../Resource`` is replaced with a platform dependent equivalent. + +In the case of multiple resource directories, the default ``ResourceFileName`` procedure retrieves either a path to the first avaliable resource, or if the resource is not available it returns a path starting with ``GenericResourceDir``. Consequently Postscript installers of Postscript resources will overwrite an existing resource or add a new one to the first resource directory. + + + +To look up fonts, after exhausting the search method described in the :ref:`next section<Font lookup>`, it concatenates together: + +#. the value of the system parameter FontResourceDir (initially ``/Resource/Font/``). +#. the name of the resource font (for instance, *Times-Roman*). + +.. note:: + + Even although the system parameters are named "somethingDir", they are not just plain directory names: they have "``/``" on the end, so that they can be concatenated with the category name or font name. + + +.. _Use_Font lookup: + +Font lookup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript has a slightly different way to find the file containing a font with a given name. This rule uses not only the search path defined by ``-I``, ``GS_LIB``, and ``GS_LIB_DEFAULT`` as :ref:`described above<How Ghostscript finds files>`, but also the directory that is the value of the ``FontResourceDir`` system parameter, and an additional list of directories that is the value of the ``GS_FONTPATH`` environment variable (or the value provided with the ``-sFONTPATH= switch``, if present). + + +At startup time, Ghostscript reads in the ``Fontmap`` files in every directory on the search path (or in the list provided with the ``-sFONTMAP=`` switch, if present): these files are catalogs of fonts and the files that contain them. (See the :ref:`documentation of fonts<Fonts.htm>` for details.) Then, when Ghostscript needs to find a font that isn't already loaded into memory, it goes through a series of steps. + +#. First, it looks up the font name in the combined Fontmaps. If there is an entry for the desired font name, and the file named in the entry can be found in some directory on the general search path (defined by ``-I``, ``GS_LIB``, and ``GS_LIB_DEFAULT``), and the file is loaded successfully, and loading it defines a font of the desired name, that is the end of the process. + +#. If this process fails at any step, Ghostscript looks for a file whose name is the concatenation of the value of the ``FontResourceDir`` system parameter and the font name, with no extension. If such a file exists, can be loaded, and defines a font of the desired name, that again is the end. The value of ``FontResourceDir`` is normally the string ``/Resource/Font/``, but it can be changed with the ``setsystemparams`` operator: see the PostScript Language Reference Manual for details. + +#. If that fails, Ghostscript then looks for a file on the general search path whose name is the desired font name, with no extension. If such a file exists, can be loaded, and defines a font of the desired name, that again is the end. + +#. If that too fails, Ghostscript looks at the ``GS_FONTPATH`` environment variable (or the value provided with the ``-sFONTPATH=`` switch, if present), which is also a list of directories. It goes to the first directory on the list, and it's descendants, looking for all files that appear to contain PostScript fonts (also Truetype fonts); it then adds all those files and fonts to the combined Fontmaps, and starts over. + +#. If scanning the first ``FONTPATH`` directory doesn't produce a file that provides the desired font, it adds the next directory on the ``FONTPATH`` list, and so on until either the font is defined successfully or the list is exhausted. + +#. Finally, if all else fails, it will try to find a substitute for the font from among the standard 35 fonts. + +.. note:: + :ref:`CID fonts<CID Fonts>` (e.g. Chinese, Japanese and Korean) are found using a different method. + + + + +Differences between search path and font path +"""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Search path + - Font path + + * - ``-I switch`` + - ``-sFONTPATH= switch`` + + * - ``GS_LIB`` and ``GS_LIB_DEFAULT`` environment variables + - ``GS_FONTPATH`` environment variable + + * - Consulted first + - Consulted only if search path and ``FontResourceDir`` don't provide the file. + + * - Font-name-to-file-name mapping given in Fontmap files; + + aliases are possible, and there need not be any relation + + between the font name in the Fontmap and the ``FontName`` in the file. + + - Font-name-to-file-name mapping is implicit – the ``FontName`` in the file is used. + + Aliases are not possible. + + * - Only fonts and files named in Fontmap are used. + - Every Type 1 font file in each directory is available; + + if TrueType fonts are supported (the ``ttfont.dev`` feature was included + + when the executable was built), they are also available. + + + +If you are using one of the following types of computer, you may wish to set the environment variable ``GS_FONTPATH`` to the value indicated so that Ghostscript will automatically acquire all the installed Type 1 (and, if supported, TrueType) fonts (but see below for notes on systems marked with "*"): + + +Suggested GS_FONTPATH for different systems +"""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + + * - System type + - GS_FONTPATH + + * - Digital Unix + - /usr/lib/X11/fonts/Type1Adobe + + * - Ultrix + - /usr/lib/DPS/outline/decwin + + * - HP-UX 9 + - /usr/lib/X11/fonts/type1.st/typefaces + + * - IBM AIX + - /usr/lpp/DPS/fonts/outlines + + /usr/lpp/X11/lib/X11/fonts/Type1 + + /usr/lpp/X11/lib/X11/fonts/Type1/DPS + + * - NeXT + - /NextLibrary/Fonts/outline + + * - SGI IRIX :ref:`*<GS_FONTPATH footnote 1>` + - /usr/lib/DPS/outline/base + + /usr/lib/X11/fonts/Type1 + + * - SunOS 4.x (NeWSprint only) + - newsprint_2.5/SUNWsteNP/reloc/$BASEDIR/NeWSprint/ + + small_openwin/lib/fonts + + * - SunOS 4.x :ref:`**<GS_FONTPATH footnote 2>` + - /usr/openwin/lib/X11/fonts/Type1/outline + + * - Solaris 2.x :ref:`**<GS_FONTPATH footnote 2>` + - /usr/openwin/lib/X11/fonts/Type1/outline + + * - VMS + - SYS$COMMON:[SYSFONT.XDPS.OUTLINE] + + + +.. _GS_FONTPATH footnote 1: + +:ref:`**<GS_FONTPATH footnote 1>` On SGI IRIX systems, you must use ``Fontmap.SGI`` in place of ``Fontmap`` or ``Fontmap.GS``, because otherwise the entries in Fontmap will take precedence over the fonts in the FONTPATH directories. + +.. _GS_FONTPATH footnote 2: + +:ref:`**<GS_FONTPATH footnote 2>` On Solaris systems simply setting ``GS_FONTPATH`` or using ``-sFONTPATH=`` may not work, because for some reason some versions of Ghostscript can't seem to find any of the Type1 fonts in ``/usr/openwin/lib/X11/fonts/Type1/outline``. (It says: "15 files, 15 scanned, 0 new fonts". We think this problem has been fixed in Ghostscript version 6.0, but we aren't sure because we've never been able to reproduce it.) See ``Fontmap.Sol`` instead. Also, on Solaris 2.x it's probably not worth your while to add Sun's fonts to your font path and Fontmap. The fonts Sun distributes on Solaris 2.x in the directories: ``/usr/openwin/lib/X11/fonts/Type1`` & ``/usr/openwin/lib/X11/fonts/Type1/outline`` are already represented among the ones distributed as part of Ghostscript; and on some test files, Sun's fonts have been shown to cause incorrect displays with Ghostscript. + + +These paths may not be exactly right for your installation; if the indicated directory doesn't contain files whose names are familiar font names like Courier and Helvetica, you may wish to ask your system administrator where to find these fonts. + +Adobe Acrobat comes with a set of fourteen Type 1 fonts, on Unix typically in a directory called ``/Acrobat3/Fonts``. There is no particular reason to use these instead of the corresponding fonts in the Ghostscript distribution (which are of just as good quality), except to save about a megabyte of disk space, but the installation documentation explains how to do it on Unix. + + + +CID fonts +~~~~~~~~~~~~~~ + +CID fonts are PostScript resources containing a large number of glyphs (e.g. glyphs for Far East languages, Chinese, Japanese and Korean). Please refer to the PostScript Language Reference, third edition, for details. + +CID font resources are a different kind of PostScript resource from fonts. In particular, they cannot be used as regular fonts. CID font resources must first be combined with a CMap resource, which defines specific codes for glyphs, before it can be used as a font. This allows the reuse of a collection of glyphs with different encodings. + +The simplest method to request a font composed of a CID font resource and a CMap resource in a PostScript document is: + + +.. code-block:: bash + + /CIDFont-CMap findfont + + +where ``CIDFont`` is a name of any CID font resource, and ``CMap`` is a name of a CMap resource designed for the same character collection. The interpreter will compose the font automatically from the specified CID font and CMap resources. Another method is possible using the ``composefont`` operator. + +CID fonts must be placed in the ``/Resource/CIDFont/`` directory. They are not found using `Font lookup`_ on the search path or font path. + + + + + + +CID font substitution +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Automatic CIDFont Substitution +"""""""""""""""""""""""""""""""""" + +In general, it is highly recommended that CIDFonts used in the creation of PDF jobs should be embedded or available to Ghostscript as CIDFont resources, this ensures that the character set, and typeface style are as intended by the author. + +In cases where the original CIDFont is not available, the next best option is to provide Ghostscript with a mapping to a suitable alternative CIDFont - see below for details on how this is achieved. However, Ghostscript does provide the ability to use a "fall back" CIDFont substitute. As shipped, this uses the DroidSansFallback.ttf font. This font contains a large number of glyphs covering several languages, but it is not comprehensive. There is, therefore, a chance that glyphs may be wrong, or missing in the output when this fallback is used. + +Internally, the font is referenced as CIDFont resource called ``CIDFallBack``, thus a different fallback from ``DroidSansFallback.ttf`` can be specified adding a mapping to your cidfmap file (see below for details) to map the name "CIDFallBack" as you prefer. For ``CIDFallBack`` the mapping must be a TrueType font or TrueType collection, it cannot be a Postscript CIDFont file. + +As with any font containing large numbers of glyphs, ``DroidSansFallback.ttf`` is quite large (~3.5Mb at the of writing). If this is space you cannot afford in your use of Ghostscript, you can simply delete the file from: ``Resource/CIDFSubst/DroidSansFallback.ttf``. The build system will cope with the file being removed, and the initialization code will avoid adding the internal fall back mapping if the file is missing. + +If ``DroidSansFallback.ttf`` is removed, and no other ``CIDFallBack`` mapping is supplied, the final "fall back" is to use a "dumb" bullet CIDFont, called ``ArtifexBullet``. As the name suggests, this will result in all the glyphs from a missing CIDFont being replaced with a simple bullet point. + +This type of generic fall back CIDFont substitution can be very useful for viewing and proofing jobs, but may not be appropriate for a "production" workflow, where it is expected that only the original font should be used. For this situation, you can supply Ghostscript with the command line option: ``-dPDFNOCIDFALLBACK``. By combining ``-dPDFNOCIDFALLBACK`` with ``-dPDFSTOPONERROR`` a production workflow can force a PDF with missing CIDFonts to error, and avoid realising a CIDFont was missing only after printing. + +The directory in which the fallback TrueType font or collection can be specified by the command line parameter ``-sCIDFSubstPath="path/to/TTF"``, or with the environment variable ``CIDFSUBSTPATH``. The file name of the substitute TrueType font can be specified using the command line parameter ``-sCIDFSubstFont="TTF file name"`` or the environment variable ``CIDFSUBSTFONT``. + + + +Explicit CIDFont Substitution +"""""""""""""""""""""""""""""""""" + +Substitution of CID font resources is controlled, by default, by the Ghostscript configuration file ``Resource/Init/cidfmap``, which defines a CID font resource map. + +The file forms a table of records, each of which should use one of three formats, explained below. Users may modify ``Resource/Init/cidfmap`` to configure Ghostscript for a specific need. Note that the default Ghostscript build includes such configuration and resource files in a rom file system built into the executable. So, to ensure your changes have an effect, you should do one of the following: rebuild the executable; use the "``-I``" command line option to add the directory containing your modified file to Ghostscript's search path; or, finally, build Ghostscript to use disk based resources. + + +Format 1 +"""""""""""""""""""""""""""""""""" + +To substitute a CID font resource with another CID font resource, add a record like this: + + +.. code-block:: bash + + /Substituted /Original ; + + +where ``Substituted`` is a name of CID font resource being used by a document, and ``Original`` is a name of an available CID font resource. Please pay attention that both them must be designed for same character collection. In other words, you cannot substitute a Japanese CID font resource with a Korean CID font resource, etc. CMap resource names must not appear in ``lib/cidfmap``. The trailing semicolon and the space before it are both required. + + +Format 2 +"""""""""""""""""""""""""""""""""" + +To substitute (emulate) a CID font resource with a TrueType font file, add a record like this: + +.. code-block:: bash + + /Substituted << keys&values >> ; + +Where ``keys&values`` are explained in the table below. + + +.. list-table:: + :header-rows: 1 + :widths: 15 15 70 + + + * - Key + - Type + - Description + + * - ``/Path`` + - string + - A path to a TrueType font file. + + This must be an absolute path. If using -dSAFER, the directory containing the font file must be on one of the permitted paths. + + * - ``/FileType`` + - name + - Must be ``/TrueType``. + + * - ``/SubfontID`` + - integer + - (optional) Index of the font in font collection, such as TTC. + + This is ignored if Path doesn't specify a collection. The first font in a collection is 0. Default value is 0. + + * - ``/CSI`` + - array of 2 or 3 elements + - (required) Information for building ``CIDSystemInfo``. + + If the array consists of 2 elements, the first element is a string, + + which specifies ``Ordering``; the second element is a number, which specifies ``Supplement``. + + | + + If the array consists of 3 elements, the first element is a string, + + which specifies ``Registry``; the second element is a string, + + which specifies ``Ordering``; the third element is a number, + + which specifies ``Supplement``. + + +Currently only CIDFontType 2 can be emulated with a TrueType font. The TrueType font must contain enough characters to cover an Adobe character collection, which is specified in ``Ordering`` and used in documents. + + +Format 3 +"""""""""""""" + +To point Ghostscript at a specific CIDFont file outside it's "normal" resource search path : + + + +.. code-block:: bash + + /CIDName (path/to/cid/font/file) ; + + +where ``CIDName`` is a name of CID font resource being used by a document, and ``path/to/cid/font/file`` is the path to the Postscript CIDFont file, including the file name. NOTE: the CIDFont file, when executed by the Postscript interpreter, must result in a CIDFont resource being defined whose CIDFontName matches the "CIDName" key for the current record. I.E. an entry with the key /PingHei-Bold must reference a file which creates a CIDFont resource called "PingHei-Bold". To substitute a file based CIDFont for a differently named CIDFont, use formats 1 and 3 in combination (the order of the entries is not important). + +The trailing semicolon and the space before it are both required. + + + +Examples +"""""""""" + +Format 1 + +.. code-block:: bash + + /Ryumin-Medium /ShinGo-Bold ; + /Ryumin-Light /MS-Mincho ; + Format 2: + /Batang << /FileType /TrueType /Path (C:/WINDOWS/fonts/batang.ttc) /SubfontID 0 /CSI [(Korea1) 3] >> ; + /Gulim << /FileType /TrueType /Path (C:/WINDOWS/fonts/gulim.ttc) /SubfontID 0 /CSI [(Korea1) 3] >> ; + /Dotum << /FileType /TrueType /Path (C:/WINDOWS/fonts/gulim.ttc) /SubfontID 2 /CSI [(Korea1) 3] >> ; + +Format 1 & 2 + +.. code-block:: bash + + /SimSun << /FileType /TrueType /Path (C:/WINDOWS/fonts/simsun.ttc) /SubfontID 0 /CSI [(GB1) 2] >> ; + /SimHei << /FileType /TrueType /Path (C:/WINDOWS/fonts/simhei.ttf) /SubfontID 0 /CSI [(GB1) 2] >> ; + /STSong-Light /SimSun ; + /STHeiti-Regular /SimHei ; + Format 3: + /PMingLiU (/usr/local/share/font/cidfont/PMingLiU.cid) ; + +Format 1 & 3 + +.. code-block:: bash + + /Ryumin-Light /PMingLiU ; + /PMingLiU (/usr/local/share/font/cidfont/PMingLiU.cid) ; + + + +The win32 installer of recent version of Ghostscript has a checkbox for "Use Windows TrueType fonts for Chinese, Japanese and Korean" to optionally update ``lib/cidfmap`` with the common CJK fonts provided by Microsoft products. The script can also be run separately (e.g. against a network drive with windows CJK fonts): + +.. code-block:: bash + + gswin32c -q -dBATCH -sFONTDIR=c:/windows/fonts -sCIDFMAP=lib/cidfmap lib/mkcidfm.ps + +Note that the font file path uses Postscript syntax. Because of this, backslashes in the paths must be represented as a double backslash. + +This can complicate substitutions for fonts with non-Roman names. For example, if a PDF file asks for a font with the name ``/#82l#82r#83S#83V#83b#83N``. This cannot be used directly in a cidfmap file because the #xx notation in names is a PDF-only encoding. Instead, try something like: + +.. code-block:: bash + + <82C68272835383568362834E>cvn << /Path (C:/WINDOWS/Fonts/msmincho.ttc) /FileType /TrueType /SubfontID 0 /CSI [(Japan1) 3] >> ; + + +Where ``<82C68272835383568362834E>`` is the same byte sequence converted to a hex string. This lets you specify a name using any sequence of bytes through the encodings available for Postscript strings. + +Note that loading truetype fonts directly from ``/Resources/CIDFont`` is no longer supported. There is no reliable way to generate a character ordering for truetype fonts. The 7.0x versions of Ghostscript supported this by assuming a Japanese character ordering. This is replaced in the 8.0x and later releases with the more general ``cidfmap`` mechanism. + +The PDF specification requires CID font files to be embedded, however some documents omit them. As a workaround the PDF interpreter applies an additional substitution method when a requested CID font resource is not embedded and it is not available. It takes values of the keys ``Registry`` and ``Ordering`` from the ``CIDFontSystem`` dictionary, and concatenates them with a dash inserted. For example, if a PDF CID font resource specifies: + + +.. code-block:: bash + + /CIDSystemInfo << /Registry (Adobe) /Ordering (CNS1) /Supplement 1 >> + + +the generated subsitituite name is ``Adobe-CNS1``. The latter may look some confusing for a font name, but we keep it for compatibility with older Ghostscript versions, which do so due to a historical reason. Add a proper record to ``lib/cidfmap`` to provide it. + +Please note that when a PDF font resource specifies: + +.. code-block:: bash + + /Registry (Adobe) /Ordering (Identity) + + +there is no way to determine the language properly. If the CID font file is not embedded, the ``Adobe-Identity`` record depends on the document and a correct record isn't possible when a document refers to multiple Far East languages. In the latter case add individual records for specific CID font names used in the document. + +Consequently, if you want to handle any PDF document with non-embedded CID fonts (which isn't a correct PDF), you need to create a suitable ``lib/cidfmap`` by hand, possibly a specific one for each document. + + + + +Using Unicode True Type fonts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ghostscript can make use of Truetype fonts with a Unicode character set. To do so, you should generate a (NOTE: non-standard!) Postscript or PDF job where the relevant text is encoded as UTF-16. Ghostscript may be used for converting such jobs to other formats (Postscript, PDF, PXL etc). The resulting output will be compliant with the spec (unlike the input). + +To render an UTF-16 encoded text, one must do the following: + +- Provide a True Type font with Unicode Encoding. It must have a ``cmap`` table with ``platformID`` equals to 3 (Windows), and ``SpecificID`` eqials to 1 (Unicode). +- Describe the font in ``Resource/Init/cidfmap`` with special values for the ``CSI`` key : ``[(Artifex) (Unicode) 0]``. +- In the PS or PDF job combine the font with one of CMap ``Identity-UTF16-H`` (for the horizontal writing mode) or ``Identity-UTF16-V`` (for the vertical writing mode). Those CMaps are distributed with Ghostscript in ``Resource/CMap``. + + +Please note that ``/Registry (Adobe) /Ordering (Identity)`` won't properly work for Unicode documents, especially for the searchability feature (see `CID font substitution`_). + + +Temporary files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Where Ghostscript puts temporary files +""""""""""""""""""""""""""""""""""""""""""" + + +.. list-table:: + :header-rows: 1 + + * - Platform + - Filename + - Location + * - MS Windows and OpenVMS + - _temp_XX.XXX + - Current directory + * - OS/2 + - gsXXXXXX + - Current directory + * - Unix + - gs_XXXXX + - /tmp + + +You can change in which directory Ghostscript creates temporary files by setting the ``TMPDIR`` or ``TEMP`` environment variable to the name of the directory you want used. Ghostscript currently doesn't do a very good job of deleting temporary files if it exits because of an error; you may have to delete them manually from time to time. + + + + +Notes on specific platforms +---------------------------------- + +Word size (32 or 64 bits) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The original PostScript language specification, while not stating a specific word size, defines 'typical' limits which make it clear that it was intended to run as a 32-bit environment. Ghostscript was originally coded that way, and the heritage remains within the code base. + +Because the Ghostscript PDF interpreter is currently written in PostScript, it proved necessary to add support for 64-bit integers so that we could process PDF files which exceed 2GB in size. This is the only real purpose in adding support for large integers, however since that time, we have made some efforts to allow for the use of 64-bit words; in particular the use of integers, but also lifting the 64K limit on strings and arrays, among other areas. + +However this is, obviously, dependent on the operating system and compiler support available. Not all builds of Ghostscript will support 64-bit integers, though some 32-bit builds (eg Windows) will. + +Even when the build supports 64-bit words, you should be aware that there are areas of Ghostscript which do not support 64-bit values. Sometimes these are dependent on the build and other times they are inherent in the architecture of Ghostscript (the graphics library does not support 64-bit co-ordinates in device space for example, and most likely never will). + + +.. note :: + + The extended support for 64-bit word size can be disabled by executing 'true .setcpsimode', This is important for checking the output of the Quality Logic test suite (and possibly other test suites) as the tests make assumptions about the sizes of integers (amongst other things). You can run ``/ghostpdl/Resource/Init/gs_cet.ps`` to change Ghostscript's behaviour so that it matches the observed behaviour of Adobe CPSI interpreters. + + +Unix +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Ghostscript distribution includes some Unix shell scripts to use with Ghostscript in different environments. These are all user-contributed code, so if you have questions, please contact the user identified in the file, not Artifex Software. + +``pv.sh`` +"""""""""""""""""""" + Preview a specified page of a ``dvi`` file in an X window + + +``sysvlp.sh`` +"""""""""""""""""""" + System V 3.2 lp interface for parallel printer + + +``pj-gs.sh`` +"""""""""""""""""""" + Printing on an H-P PaintJet under HP-UX + + +``unix-lpr.sh`` +"""""""""""""""""""" + Queue filter for ``lpr`` under Unix; its documentation is intended for system administrators + + +``lprsetup.sh`` +"""""""""""""""""""" + Setup for ``unix-lpr.sh`` + + + +VMS +~~~~~~~~~ + +To be able to specify switches and file names when invoking the interpreter, define ``gs`` as a foreign command: + + +.. code-block:: bash + + $ gs == "$disk:[directory]gs.exe" + + +where the "disk" and "directory" specify where the Ghostscript executable is located. For instance: + +.. code-block:: bash + + $ gs == "$dua1:[ghostscript]gs.exe" + + +On VMS systems, the last character of each "directory" name indicates what sort of entity the "directory" refers to. If the "directory" name ends with a colon "``:``", it is taken to refer to a logical device, for instance: + +.. code-block:: bash + + $ define ghostscript_device dua1:[ghostscript_510] + +.. code-block:: bash + + $ define gs_lib ghostscript_device: + +If the "directory" name ends with a closing square bracket "``]``", it is taken to refer to a real directory, for instance + +.. code-block:: bash + + $ define gs_lib dua1:[ghostscript] + +Defining the logical ``GS_LIB``: + + +.. code-block:: bash + + $ define gs_lib disk:[directory] + +allows Ghostscript to find its initialization files in the Ghostscript directory even if that's not where the executable resides. + + +Although VMS DCL itself converts unquoted parameters to upper case, C programs such as Ghostscript receive their parameters through the C runtime library, which forces all unquoted command-line parameters to lower case. That is, with the command: + +.. code-block:: bash + + $ gs -Isys$login: + + +Ghostscript sees the switch as ``-isys$login``, which doesn't work. To preserve the case of switches, quote them like this: + +.. code-block:: bash + + $ gs "-Isys$login:" + + +If you write printer output to a file with ``-sOutputFile=`` and then want to print the file later, use ``"PRINT/PASSALL"``. + +PDF files (or PostScript files that use the ``setfileposition`` operator) must be "stream LF" type files to work properly on VMS systems. (Note: This definitely matters if Ghostscript was compiled with ``DEC C``; we are not sure of the situation if you use ``gcc``.) Because of this, if you transfer files by FTP, you probably need to do one of these two things after the transfer: + + +- If the FTP transfer was in text (ASCII) mode: + +.. code-block:: bash + + $ convert/fdl=streamlf.fdl input-file output-file + + +where the contents of the file ``STREAMLF.FDL`` are: + + +.. blockquote + + +FILE + + ORGANIZATION sequential + + RECORD + + BLOCK_SPAN yes + + CARRIAGE_CONTROL carriage_return + + FORMAT stream_lf + + + +- If the FTP transfer was in binary mode: + +.. code-block:: bash + + $ set file/attribute=(rfm:stmlf) + + + +Using X Windows on VMS +""""""""""""""""""""""""""" + +If you are using on an X Windows display, you can set it up with the node name and network transport, for instance: + +.. code-block:: bash + + $ set display/create/node="doof.city.com"/transport=tcpip + +and then run Ghostscript by typing ``gs`` at the command line. + + + + +MS Windows +~~~~~~~~~~~~~~ + +The name of the Ghostscript command line executable on MS Windows is ``gswin32c/gswin64c`` so use this instead of the plain '``gs``' in the quickstart examples. + +To run the batch files in the Ghostscript lib directory, you must add ``gs\bin`` and ``gs\lib`` to the ``PATH``, where ``gs`` is the top-level Ghostscript directory. + +When passing options to Ghostscript through a batch file wrapper such as ``ps2pdf.bat`` you need to substitute '#' for '=' as the separator between options and their arguments. For example: + + +.. code-block:: bash + + ps2pdf -sPAPERSIZE#a4 file.ps file.pdf + + +Ghostscript treats '#' the same internally, and the '=' is mangled by the command shell. + +There is also an older version for MS Windows called just ``gswin32`` that provides its own window for the interactive postscript prompt. The executable ``gswin32c/gswin64c`` is usually the better option since it uses the native command prompt window. + +For printer devices, the default output is the default printer. This can be modified as follows: + + +.. code-block:: bash + + -sOutputFile="%printer%printer name" + + +Output to the named printer. If your printer is named "HP DeskJet 500" then you would use ``-sOutputFile="%printer%HP DeskJet 500"``. + + +MS-DOS +~~~~~~~~~~~~~~ + + +.. note:: + + Ghostscript is no longer supported on MS-DOS. + +Invoking Ghostscript from the command prompt in Windows is supported by the Windows executable described above. + + + + +X Windows +~~~~~~~~~~~~~~ + +Ghostscript looks for the following resources under the program name ``ghostscript`` and class name ``Ghostscript``; the ones marked "**" are calculated from display metrics: + +X Windows resources +""""""""""""""""""""" + + +.. list-table:: + :header-rows: 1 + + * - Name + - Class + - Default + * - background + - Background + - white + * - foreground + - Foreground + - black + * - borderColor + - BorderColor + - black + * - borderWidth + - BorderWidth + - 1 + * - geometry + - Geometry + - NULL + * - xResolution + - Resolution + - :sub:`**` + * - yResolution + - Resolution + - :sub:`**` + * - useExternalFonts + - UseExternalFonts + - true + * - useScalableFonts + - UseScalableFonts + - true + * - logExternalFonts + - LogExternalFonts + - false + * - externalFontTolerance + - ExternalFontTolerance + - 10.0 + * - palette + - Palette + - Color + * - maxGrayRamp + - MaxGrayRamp + - 128 + * - maxRGBRamp + - MaxRGBRamp + - 5 + * - maxDynamicColors + - MaxDynamicColors + - 256 + * - useBackingPixmap + - UseBackingPixmap + - true + * - useXPutImage + - UseXPutImage + - true + * - useXSetTile + - UseXSetTile + - true + + +X resources +""""""""""""""" + +To set X resources, put them in a file (such as ``~/.Xdefaults`` on Unix) in a form like this: + +.. list-table:: + + * - Ghostscript*geometry: + - 595x842-0+0 + * - Ghostscript*xResolution: + - 72 + * - Ghostscript*yResolution: + - 72 + + +Then merge these resources into the X server's resource database: + + +.. code-block:: bash + + xrdb -merge ~/.Xdefaults + + +- Ghostscript doesn't look at the default system background and foreground colors; if you want to change the background or foreground color, you must set them explicitly for Ghostscript. This is a deliberate choice, so that PostScript documents will display correctly by default -- with white as white and black as black -- even if text windows use other colors. +- The ``geometry`` resource affects only window placement. +- Resolution is expressed in pixels per inch (1 inch = 25.4mm). +- The font tolerance gives the largest acceptable difference in height of the screen font, expressed as a percentage of the height of the desired font. +- The ``palette`` resource can be used to restrict Ghostscript to using a grayscale or monochrome palette. + +``maxRGBRamp`` and ``maxGrayRamp`` control the maximum number of colors that Ghostscript allocates ahead of time for the dither cube (ramp). Ghostscript never preallocates more than half the cells in a colormap. ``maxDynamicColors`` controls the maximum number of colors that Ghostscript will allocate dynamically in the colormap. + +Working around bugs in X servers +"""""""""""""""""""""""""""""""""""" + +The "``use...``" resources exist primarily to work around bugs in X servers. + +- Old versions of DEC's X server (DECwindows) have bugs that require setting ``useXPutImage`` or ``useXSetTile`` to false. +- Some servers do not implement backing pixmaps properly, or do not have enough memory for them. If you get strange behavior or "out of memory" messages, try setting ``useBackingPixmap`` to ``false``. +- Some servers do not implement tiling properly. This appears as broad bands of color where dither patterns should appear. If this happens, try setting ``useXSetTile`` to ``false``. +- Some servers do not implement bitmap or pixmap displaying properly. This may appear as white or black rectangles where characters should appear; or characters may appear in "inverse video" (for instance, white on a black rectangle rather than black on white). If this happens, try setting ``useXPutImage`` to ``false``. + + +X device parameters +""""""""""""""""""""""""""""" + In addition to the device parameters recognized by all devices, Ghostscript's X driver provides parameters to adjust its performance. Users will rarely need to modify these. Note that these are parameters to be set with the ``-d`` switch in the command line (e.g., ``-dMaxBitmap=10000000``), not resources to be defined in the ``~/.Xdefaults`` file. + +``AlwaysUpdate <boolean>`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + If ``true``, the driver updates the screen after each primitive drawing operation; if ``false`` (the default), the driver uses an intelligent buffered updating algorithm. + +``MaxBitmap <integer>`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + If the amount of memory required to hold the pixmap for the window is no more than the value of ``MaxBitmap``, the driver will draw to a pixmap in Ghostscript's address space (called a "client-side pixmap") and will copy it to the screen from time to time; if the amount of memory required for the pixmap exceeds the value of ``MaxBitmap``, the driver will draw to a server pixmap. Using a client-side pixmap usually provides better performance -- for bitmap images, possibly much better performance -- but since it may require quite a lot of RAM (e.g., about 2.2 Mb for a 24-bit 1024x768 window), the default value of ``MaxBitmap`` is 0. + + +``MaxTempPixmap, MaxTempImage <integer>`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + These control various aspects of the driver's buffering behavior. For details, please consult the source file ``gdevx.h``. + + +SCO Unix +""""""""""""" + +Because of bugs in the SCO Unix kernel, Ghostscript will not work if you select direct screen output and also allow it to write messages on the console. If you are using direct screen output, redirect Ghostscript's terminal output to a file. + + + + +.. _Use_Command line options: + + +Command line options +----------------------- + +Unless otherwise noted, these switches can be used on all platforms. + + +General switches +~~~~~~~~~~~~~~~~~~~ + +.. _Use_Input Control: + +Input control +"""""""""""""""""" + +**@filename** +^^^^^^^^^^^^^^^^^ + Causes Ghostscript to read filename and treat its contents the same as the command line. (This was intended primarily for getting around DOS's 128-character limit on the length of a command line.) Switches or file names in the file may be separated by any amount of white space (space, tab, line break); there is no limit on the size of the file. + +**--** *filename arg1 ...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-+** *filename arg1 ...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Takes the next argument as a file name as usual, but takes all remaining arguments (even if they have the syntactic form of switches) and defines the name ``ARGUMENTS`` in userdict (not systemdict) as an array of those strings, before running the file. When Ghostscript finishes executing the file, it exits back to the shell. + +**-@** *filename arg1 ...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Does the same thing as -- and -+, but expands @filename arguments. + +**-** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-_** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + These are not really switches: they tell Ghostscript to read from standard input, which is coming from a file or a pipe, with or without buffering. On some systems, Ghostscript may read the input one character at a time, which is useful for programs such as ghostview that generate input for Ghostscript dynamically and watch for some response, but can slow processing. If performance is significantly slower than with a named file, try '-_' which always reads the input in blocks. However, '-' is equivalent on most systems. + +**-c** *token ...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-c** *string ...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Interprets arguments as PostScript code up to the next argument that begins with "-" followed by a non-digit, or with "@". For example, if the file ``quit.ps`` contains just the word "``quit``", then ``-c quit`` on the command line is equivalent to ``quit.ps`` there. Each argument must be valid PostScript, either individual tokens as defined by the token operator, or a string containing valid PostScript. + + Because Ghostscript must initialize the PostScript environment before executing the commands specified by this option it should be specified after other setup options. Specifically this option 'bind's all operations and sets the systemdict to readonly. + +**-f** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Interprets following non-switch arguments as file names to be executed using the normal run command. Since this is the default behavior, ``-f`` is useful only for terminating the list of tokens for the ``-c`` switch. + +**-f** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Execute the given file, even if its name begins with a "-" or "@". + + +File searching +"""""""""""""""""""""""""""""""""" + +Note that by "library files" here we mean all the files identified using the search rule under "`How Ghostscript finds files`_" above: Ghostscript's own initialization files, fonts, and files named on the command line. + +.. _I switch: + +**-I** *directories* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Adds the designated list of directories at the head of the search path for library files. + +.. _P switch: + +**-P** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Makes Ghostscript look first in the current directory for library files. + +**-P-** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Makes Ghostscript not look first in the current directory for library files (unless, of course, the first explicitly supplied directory is "."). This is now the default. + + +.. _Use_Setting Parameters: + +Setting parameters +""""""""""""""""""""""""""""""""""" + +**-D** *name*, **-d** *name* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Define a name in systemdict with value=true. + +**-D** *name=token*, **-d** *name=token* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Define a name in systemdict with the given value. The value must be a valid PostScript token (as defined by the ``token`` operator). If the token is a non-literal name, it must be true, false, or null. It is recommeded that this is used only for simple values -- use ``-c`` (above) for complex values such as procedures, arrays or dictionaries. + + Note that these values are defined before other names in systemdict, so any name that that conflicts with one usually in systemdict will be replaced by the normal definition during the interpreter initialization. + +**-S** *name=string*, **-s** *name=string* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Define a name in systemdict with a given string as value. This is different from ``-d``. For example, ``-dXYZ=35`` on the command line is equivalent to the program fragment: + +.. code-block:: bash + + /XYZ 35 def + +whereas ``-sXYZ=35`` is equivalent to: + +.. code-block:: bash + + /XYZ (35) def + + + +**-p** *name=string* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Define a name in systemdict with the parsed version of the given string as value. The string takes a parameter definition in (something very close to) postscript format. This allows more complex structures to be passed in than is possible with ``-d`` or ``-s``. For example: + +.. code-block:: bash + + -pFoo="<< /Bar[1 2 3]/Baz 0.1 /Whizz (string) /Bang <0123> >>" + + This means that ``-p`` can do the job of both ``-d`` and ``-s``. For example: + +.. code-block:: bash + + -dDownScaleFactor=3 + + can be equivalently performed by: + +.. code-block:: bash + + -pDownScaleFactor=3 + + and: + +.. code-block:: bash + + -sPAPERSIZE=letter + + can be equivalently performed by: + +.. code-block:: bash + + -pPAPERSIZE="(letter)" + + + .. note :: + + There are some 'special' values that should be set using ``-s``, not ``-p``, such as ``DEVICE`` and ``DefaultGrayProfile``. Broadly, only use ``-p`` if you cannot set what you want using ``-s`` or ``-d``. + + Also, internally, after setting an parameter with ``-p`` we perform an ``initgraphics`` operation. This is required to allow changes in parameters such as ``HWResolution`` to take effect. This means that attempting to use ``-p`` other than at the start of a page is liable to give unexpected results. + + +**-u** *name* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Un-define a name, cancelling ``-d`` or ``-s``. + + Note that the initialization file gs_init.ps makes systemdict read-only, so the values of names defined with ``-D``, ``-d``, ``-S``, and ``-s`` cannot be changed -- although, of course, they can be superseded by definitions in userdict or other dictionaries. However, device parameters set this way (PageSize, Margins, etc.) are not read-only, and can be changed by code in PostScript files. + +**-g** *number1 x number2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Equivalent to ``-dDEVICEWIDTH=number1`` and ``-dDEVICEHEIGHT=number2``, specifying the device width and height in pixels for the benefit of devices such as X11 windows and VESA displays that require (or allow) you to specify width and height. Note that this causes documents of other sizes to be clipped, not scaled: see ``-dFIXEDMEDIA`` below. + +**-r** *number* (same as *-r number x number*) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-r** *number1 x number2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Equivalent to ``-dDEVICEXRESOLUTION=number1`` and ``-dDEVICEYRESOLUTION=number2``, specifying the device horizontal and vertical resolution in pixels per inch for the benefit of devices such as printers that support multiple X and Y resolutions. + + + +Suppress messages +"""""""""""""""""""""""""""""""""""""" + +**-q** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Quiet startup: suppress normal startup messages, and also do the equivalent of :ref:`-dQUIET<DQUIET>`. + + +Parameter switches (-d and -s) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + As noted above, ``-d`` and ``-s`` define initial values for PostScript names. Some of these names are parameters that control the interpreter or the graphics engine. You can also use ``-d`` or ``-s`` to define a value for any device parameter of the initial device (the one defined with ``-sDEVICE=``, or the default device if this switch is not used). For example, since the :title:`ppmraw` device has a numeric ``GrayValues`` parameter that controls the number of bits per component, ``-sDEVICE=ppmraw -dGrayValues=16`` will make this the default device and set the number of bits per component to 4 (log2(16)). + + +Rendering parameters +""""""""""""""""""""""""""""""" + +**-dCOLORSCREEN** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-dCOLORSCREEN=0** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-dCOLORSCREEN=false** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + On high-resolution devices (at least 150 dpi resolution, or ``-dDITHERPPI`` specified), ``-dCOLORSCREEN`` forces the use of separate halftone screens with different angles for CMYK or RGB if halftones are needed (this produces the best-quality output); ``-dCOLORSCREEN=0`` uses separate screens with the same frequency and angle; ``-dCOLORSCREEN=false`` forces the use of a single binary screen. The default if ``COLORSCREEN`` is not specified is to use separate screens with different angles if the device has fewer than 5 bits per color, and a single binary screen (which is never actually used under normal circumstances) on all other devices. + + +**-dDITHERPPI=** *lpi* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Forces all devices to be considered high-resolution, and forces use of a halftone screen or screens with *lpi* lines per inch, disregarding the actual device resolution. Reasonable values for lpi are N/5 to N/20, where N is the resolution in dots per inch. + +**-dInterpolateControl=** *control_value* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This allows control of the image interpolation. + + By default ``InterpolateControl`` is 1 and the image rendering for images that have ``/Interpolate true`` are interpolated to the full device resolution. Otherwise, images are rendered using the nearest neighbour scaling (Bresenham's line algorithm through the image, plotting the closest texture coord at each pixel). When downscaling this results in some source pixels not appearing at all in the destination. When upscaling, each source pixels will cover at least one destination pixel. + + When the *control_value* is 0 no interpolation is performed, whether or not the file has images with ``/Interpolate true``. + + When the *control_value* is greater than 1 interpolation is performed for images with ``/Interpolate true`` as long as the image scaling factor on either axis is larger than the *control_value*. Also, the interpolation only produces images that have (device resolution / *control_value*) maximum resolution rather than full device resolution. This allows for a performance vs. quality tradeoff since the number of pixels produced by the interpolation will be a fraction of the interpolated pixels at full device resolution. Every source pixel will contribute partially to the destination pixels. + + When the ``InterpolateControl`` *control_value* is less than 0 interpolation is forced as if all images have ``/Interpolate true``, and the interpolation is controlled by the absolute value of the *control_value* as described above. Thus, ``-dInterpolateControl=-1`` forces all images to be interpolated at full device resolution. + + Computationally, image interpolation is much more demanding than without interpolation (lots of floating point muliplies and adds for every output pixel vs simple integer additions, subtractions, and shifts). + + In all but special cases image interpolation uses a Mitchell filter function to scale the contributions for each output pixel. When upscaling, every output pixel ends up being the weighted sum of 16 input pixels, When downscaling more source pixels will contribute to the interpolated pixels. Every source pixel has some effect on the output pixels. + + +**-dDOINTERPOLATE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option still works, but is deprecated, and is the equivalent of ``-dInterpolateControl=-1``. + + +**-dNOINTERPOLATE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option still works, but is deprecated and is the equivalent of ``-dInterpolateControl=0``. + + Turns off image interpolation, improving performance on interpolated images at the expense of image quality. ``-dNOINTERPOLATE`` overrides ``-dDOINTERPOLATE``. + + +**-dTextAlphaBits=** *n* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-dGraphicsAlphaBits=** *n* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + These options control the use of subsample antialiasing. Their use is highly recommended for producing high quality rasterizations. The subsampling box size n should be 4 for optimum output, but smaller values can be used for faster rendering. Antialiasing is enabled separately for text and graphics content. Allowed values are 1, 2 or 4. + + +.. note :: + Because of the way antialiasing blends the edges of shapes into the background when they are drawn some files that rely on joining separate filled polygons together to cover an area may not render as expected with ``GraphicsAlphaBits`` at 2 or 4. If you encounter strange lines within solid areas, try rendering that file again with ``-dGraphicsAlphaBits=1``. + + Further note: because this feature relies upon rendering the input it is incompatible, and will generate an error on attempted use, with any of the vector output devices. + + + +**-dAlignToPixels=** *n* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Chooses glyph alignent to integral pixel boundaries (if set to the value 1) or to subpixels (value 0). Subpixels are a smaller raster grid which is used internally for text antialiasing. The number of subpixels in a pixel usually is ``2^TextAlphaBits``, but this may be automatically reduced for big characters to save space in character cache. + + The parameter has no effect if ``-dTextAlphaBits=1``. Default value is 0. + + Setting ``-dAlignToPixels=0`` can improve rendering of poorly hinted fonts, but may impair the appearance of well-hinted fonts. + +**-dGridFitTT=** *n* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This specifies the initial value for the implementation specific user parameter :ref:`GridFitTT<Language_GridFitTT>`. It controls grid fitting of True Type fonts (Sometimes referred to as "hinting", but strictly speaking the latter is a feature of Type 1 fonts). Setting this to 2 enables automatic grid fitting for True Type glyphs. The value 0 disables grid fitting. The default value is 2. For more information see the description of the user parameter :ref:`GridFitTT<Language_GridFitTT>`. + + +**-dUseCIEColor** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set ``UseCIEColor`` in the page device dictionary, remapping device-dependent color values through a Postscript defined CIE color space. Document ``DeviceGray``, ``DeviceRGB`` and ``DeviceCMYK`` source colors will be substituted respectively by Postscript CIEA, CIEABC and CIEDEFG color spaces. See the document `GS9 Color Management`_ for details on how this option will interact with Ghostscript's ICC-based color workflow. If accurate colors are desired, it is recommended that an ICC workflow be used. + +**-dNOCIE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Substitutes ``DeviceGray`` for CIEBasedA, DeviceRGB for CIEBasedABC and CIEBasedDEF spaces and ``DeviceCMYK`` for CIEBasedDEFG color spaces. Useful only on very slow systems where color accuracy is less important. + + +**-dNOSUBSTDEVICECOLORS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This switch prevents the substitution of the ``ColorSpace`` resources (``DefaultGray``, ``DefaultRGB``, and ``DefaultCMYK``) for the ``DeviceGray``, ``DeviceRGB``, and ``DeviceCMYK`` color spaces. This switch is primarily useful for PDF creation using the :title:`pdfwrite` device when retaining the color spaces from the original document is important. + +**-dNOPSICC** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables the automatic loading and use of an input color space that is contained in a PostScript file as DSC comments starting with the %%BeginICCProfile: comment. ICC profiles are sometimes embedded by applications to convey the exact input color space allowing better color fidelity. Since the embedded ICC profiles often use multidimensional RenderTables, color conversion may be slower than using the Default color conversion invoked when the ``-dUseCIEColor`` option is specified, therefore the ``-dNOPSICC`` option may result in improved performance at slightly reduced color fidelity. + + +**-dNOTRANSPARENCY** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Turns off PDF 1.4 transparency, resulting in faster (but possibly incorrect) rendering of pages containing PDF 1.4 transparency and blending. + +**-dALLOWPSTRANSPARENCY** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Enables the use of the Ghostscript custom transparency operators (:ref:`Transparency<Language_Transparency>`) from Postscript input. Normally, these operators are not accessible from Postscript jobs, being primarily intended to be called by the PDF interpreter. Using ``-dALLOWPSTRANSPARENCY`` leaves them available. It is important that these operators are used correctly, especially the order in which they are called, otherwise unintended, even undefined behavior may result. + +**-dNO_TN5044** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Turns off the TN 5044 psuedo operators. These psuedo operators are not a part of the official Postscript specification. However they are defined in Technical Note #5044 Color Separation Conventions for PostScript Language Programs. These psuedo operators are required for some files from QuarkXPress. However some files from Corel 9 and Illustrator 88 do not operate properly if these operators are present. + +**-dDOPS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Enables processing of Subtype /PS streams in PDF files and the DoPS operator. DoPS has in fact been deprecated for some time. Also the "PS" operator that was removed from the 1.3 2nd edition specification is also disabled by default, and enabled by ``-dDOPS``. Use of this option is NOT recommended in security-conscious applications, as it increases the scope for malicious code. ``-dDOPS`` has no effect on processing of PostScript source files. Note: in releases 7.30 and earlier, processing of DoPS was always enabled. + +**-dBlackText** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Forces text to be drawn with black. This occurs for text fill and text stroke operations. PDF output created with this setting will be updated to be drawn with gray values of 0. Type 3 fonts, which are sometimes used for graphics, are not affected by this parameter. Note, works only for fills with gray, rgb, and cmyk. Pattern, separation, and deviceN fills will not be affected. + + +**-dBlackVector** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Forces vector stroke and fills to be drawn with black. PDF output created with this setting will be updated to be drawn with gray values of 0. Note, works only for fills with gray, rgb, and cmyk. Pattern, separation, and deviceN fills will not be affected. + + +**-dBlackThresholdL=** *float* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Sets the threshold for the luminance value (L*) at which that value and above will be mapped to white when using the ``BlackText`` and ``BlackVector`` option. Default is 90. Pure white has a value of 100. Pure black has a value of 0. This means that if you set ``BlackThresholdL=101``, all colors will be mapped to black. If you set ``BlackThresholdL=75``, colors that are below an L* value of 75 will be mapped to black. Colors at or above an L* of 75 will be mapped to white, depending upon the setting of ``BlackThresholdC`` (see below). + + +**-dBlackThresholdC=** *float* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + For colors that are at or above the value set by ``BlackThresholdL`` (or the default setting of 90), map colors to white that are within a distance of ``BlackThresholdC`` from the CIELAB neutral axis in terms of the L1 norm on the a* and b* value. All others are mapped to black. This has the effect of forcing colors with high luminance and high chrominance to black (e.g. pure yellow) while those with a lower luminance and less chrominance to white (e.g. a light gray). Default value is 3. You can visualize the region that is mapped to white as a cuboid that is centered on the CIELAB neutral axis with one end tied to the L*=100 value. The cuboid cross sections across the neutral axis are squares whose size is set by ``BlackThresholdC``. The cuboid length is set by ``BlackThresholdL`` and is effectively ``100-BlackThresholdL``. + + + +Page parameters +""""""""""""""""""""""""""""""" + + +**-dFirstPage=** *pagenumber* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Begin on the designated page of the document. Pages of all documents in PDF collections are numbered sequentionally. + + +**-dLastPage=** *pagenumber* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Stop after the designated page of the document. Pages of all documents in PDF collections are numbered sequentionally. + +**-sPageList=** *pagenumber* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + There are three possible values for this; even, odd or a list of pages to be processed. A list can include single pages or ranges of pages. Ranges of pages use the minus sign '-', individual pages and ranges of pages are separated by commas ','. A trailing minus '-' means process all remaining pages. For example: + +.. code-block:: bash + + -sPageList=1,3,5 indicates that pages 1, 3 and 5 should be processed. + -sPageList=5-10 indicates that pages 5, 6, 7, 8, 9 and 10 should be processed. + -sPageList=1, 5-10, 12- indicates that pages 1, 5, 6, 7, 8, 9, 10 and 12 onwards should be processed. + + + The PDF interpreter and the other language interpreters handle these in slightly different ways. Because PDF files enable random access to pages in the document the PDF inerpreter only interprets and renders the required pages. PCL and PostScript cannot be handled in ths way, and so all the pages must be interpreted. However only the requested pages are rendered, which can still lead to savings in time. Be aware that using the '``%d``' syntax for ``OutputFile`` does not reflect the page number in the original document. If you chose (for example) to process even pages by using ``-sPageList=even``, then the output of ``-sOutputFile=out%d.png`` would still be ``out0.png``, ``out1.png``, ``out2.png`` etc. + + Because the PostScript and PCL interpreters cannot determine when a document terminates, sending multple files as input on the command line does not reset the ``PageList`` between each document, each page in the second and subsequent documents is treated as following on directly from the last page in the first document. The PDF interpreter, however, does not work this way. Since it knows about individual PDF files the ``PageList`` is applied to each PDF file separately. So if you were to set ``-sPageList=1,2`` and then send two PDF files, the result would be pages 1 and 2 from the first file, and then pages 1 and 2 from the second file. The PostScript interpreter, by contrast, would only render pages 1 and 2 from the first file. This means you must exercise caution when using this switch, and probably should not use it at all when processing a mixture of PostScript and PDF files on the same command line. + +.. _FIXEDMEDIA: + +**-dFIXEDMEDIA** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes the media size to be fixed after initialization, forcing pages of other sizes or orientations to be clipped. This may be useful when printing documents on a printer that can handle their requested paper size but whose default is some other size. Note that ``-g`` automatically sets ``-dFIXEDMEDIA``, but ``-sPAPERSIZE=`` does not. + +**-dFIXEDRESOLUTION** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes the media resolution to be fixed similarly. ``-r`` automatically sets ``-dFIXEDRESOLUTION``. + +**-dPSFitPage** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The page size from the PostScript file ``setpagedevice`` operator, or one of the older ``statusdict`` page size operators (such as ``letter`` or ``a4``) will be rotated, scaled and centered on the "best fit" page size from those availiable in the ``InputAttributes`` list. The ``-dPSFitPage`` is most easily used to fit pages when used with the ``-dFIXEDMEDIA`` option. + + This option is also set by the ``-dFitPage`` option. + +**-dORIENT1=true** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-dORIENT1=false** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Defines the meaning of the 0 and 1 orientation values for the ``setpage[params]`` compatibility operators. The default value of ``ORIENT1`` is true (set in ``gs_init.ps``), which is the correct value for most files that use ``setpage[params]`` at all, namely, files produced by badly designed applications that "know" that the output will be printed on certain roll-media printers: these applications use 0 to mean landscape and 1 to mean portrait. ``-dORIENT1=false`` declares that 0 means portrait and 1 means landscape, which is the convention used by a smaller number of files produced by properly written applications. + +**-dDEVICEWIDTHPOINTS=** *w* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**-dDEVICEHEIGHTPOINTS=** *h* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Sets the initial page width to w or initial page height to h respectively, specified in 1/72" units. + +**-sDEFAULTPAPERSIZE=** *a4* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This value will be used to replace the device default papersize ONLY if the default papersize for the device is 'letter' or 'a4' serving to insulate users of A4 or 8.5x11 from particular device defaults (the collection of contributed drivers in Ghostscript vary as to the default size). + +**-dFitPage** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This is a "convenience" operator that sets the various options to perform page fitting for specific file types. + This option sets the ``-dEPSFitPage``, ``-dPDFFitPage``, and the ``-dFitPage`` options. + + +**-sNupControl=** *Nup_option_string* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option specifies the N-up nesting to be performed. The pages are scaled and arranged on the current ``PageSize`` "master" page according the the option. + + The only option strings are as follows: + + ``-sNupControl=number1xnumber2`` + Will fit *number1* nested pages across the master page, and *number2* down the master page, from the upper left, then to the right to fill the row, moving down to the leftmost place on the next row until the nest is complete. + A partially filled nest will be output when the ``-sNupControl=`` *string* is changed, when Ghostscript exits, or when the page size changes. + + Pages are scaled to fit the requested number horizontally and vertically, maintaining the aspect ratio. If the scaling selected for fitting the nested pages leaves space horizontally on the master page, the blank area will be added to the left and right of the entire row of nested pages. If the fit results in vertical space, the blank area will be added above and below all of the rows. + + ``-sNupControl=`` + An empty string will turn off nesting. If there are any nested pages on the master page, the partially filled master page will be output. + Printer devices typically reallocate their memory whenever the transparency use of a page changes (from one page having transparency, to the next page not having transparency, or vice versa). This would cause problems with Nup, possibly leading to lost or corrupt pages in the output. To avoid this, the Nup device changes the parameters of the page to always set the ``PageUsesTransparency`` flag. While this should be entirely transparent for the user and not cause extra transparency blending operations during the standard rendering processes for most devices, it may cause devices to use the clist rather than PageMode. + + +Font-related parameters +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +**-dLOCALFONTS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes Type 1 fonts to be loaded into the current VM -- normally local VM -- instead of always being loaded into global VM. Useful only for compatibility with Adobe printers for loading some obsolete fonts. + +.. _UseDNoFontMap: + +**-dNOFONTMAP** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Suppresses the normal loading of the ``Fontmap`` file. This may be useful in environments without a file system. + +**-dNOFONTPATH** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Suppresses consultation of ``GS_FONTPATH``. This may be useful for debugging. + +**-dNOPLATFONTS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables the use of fonts supplied by the underlying platform (X Windows or Microsoft Windows). This may be needed if the platform fonts look undesirably different from the scalable fonts. + +**-dNONATIVEFONTMAP** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables the use of font map and corresponding fonts supplied by the underlying platform. This may be needed to ensure consistent rendering on the platforms with different fonts, for instance, during regression testing. + +**-sFONTMAP=** *filename1;filename2;...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specifies alternate name or names for the ``Fontmap`` file. Note that the names are separated by ":" on Unix systems, by ";" on MS Windows systems, and by "," on VMS systems, just as for search paths. + +**-sFONTPATH=** *dir1;dir2;...* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specifies a list of directories that will be scanned when looking for fonts not found on the search path, overriding the environment variable ``GS_FONTPATH``. + + By implication, any paths specified by ``FONTPATH`` or ``GS_FONTPATH`` are automatically added to the permit file read list (see ":ref:`-dSAFER<dSAFER>`"). + +**-sSUBSTFONT=** *fontname* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes the given font to be substituted for all unknown fonts, instead of using the normal intelligent substitution algorithm. Also, in this case, the font returned by findfont is the actual font named fontname, not a copy of the font with its ``FontName`` changed to the requested one. + + +.. note :: + + THIS OPTION SHOULD NOT BE USED WITH HIGH LEVEL (VECTOR) DEVICES, such as :title:`pdfwrite`, because it prevents such devices from providing the original font names in the output document. The font specified (fontname) will be embedded instead, limiting all future users of the document to the same approximate rendering. + + + +.. _resource related parameters: + + +Resource-related parameters +"""""""""""""""""""""""""""""" + +**-sGenericResourceDir=** *path* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specifies a path to resource files. The value is platform dependent. It must end with a directory separator. + A note for Windows users, Artifex recommends the use of the forward slash delimiter due to the special interpretation of ``\"`` by the Microsoft C startup code. See `Parsing C Command-Line Arguments`_ for more information. + + Adobe specifies ``GenericResourceDir`` to be an absolute path to a single resource directory. Ghostscript instead maintains multiple resource directories and uses an extended method for finding resources, which is explained in :ref:`"Finding PostScript Level 2 resources"<PS resources>`. + + Due to the extended search method, Ghostscript uses ``GenericResourceDir`` only as a default directory for resources being not installed. Therefore ``GenericResourceDir`` may be considered as a place where new resources to be installed. The default implementation of the function ``ResourceFileName`` uses ``GenericResourceDir`` when it is an absolute path, or when the resource file is absent. + + The extended search method does not call ``ResourceFileName``. + + Default value is (``./Resource/``) for Unix, and an equivalent one on other platforms. + +**-sFontResourceDir=** *path* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specifies a path where font files are installed. It's meaning is similar to ``GenericResourceDir``. + + Default value is (``./Font/``) for Unix, and an equivalent one on other platforms. + + + +.. _Interaction related parameters: + +Interaction-related parameters +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + +**-dBATCH** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes Ghostscript to exit after processing all files named on the command line, rather than going into an interactive loop reading PostScript commands. Equivalent to putting ``-c`` quit at the end of the command line. + +**-dNOPAGEPROMPT** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables only the prompt, but not the pause, at the end of each page. This may be useful on PC displays that get confused if a program attempts to write text to the console while the display is in a graphics mode. + +**-dNOPAUSE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables the prompt and pause at the end of each page. Normally one should use this (along with ``-dBATCH``) when producing output on a printer or to a file; it also may be desirable for applications where another program is "driving" Ghostscript. + +**-dNOPROMPT** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables the prompt printed by Ghostscript when it expects interactive input, as well as the end-of-page prompt (``-dNOPAGEPROMPT``). This allows piping input directly into Ghostscript, as long as the data doesn't refer to ``currentfile``. + + +.. _DQUIET: + +**-dQUIET** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Suppresses routine information comments on standard output. This is currently necessary when redirecting device output to standard output. + +**-dSHORTERRORS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Makes certain error and information messages more Adobe-compatible. + +**-sstdout=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Redirect PostScript ``%stdout`` to a file or ``stderr``, to avoid it being mixed with device ``stdout``. To redirect ``stdout`` to ``stderr`` use ``-sstdout=%stderr``. To cancel redirection of stdout use ``-sstdout=%stdout`` or ``-sstdout=-``. + +.. note:: + + This redirects PostScript output to ``%stdout`` but does not change the destination FILE of device output as with ``-sOutputFile=-`` or even ``-sOutputFile=%stdout`` since devices write directly using the stdout ``FILE *`` pointer with C function calls such as ``fwrite`` or ``fputs``. + +**-dTTYPAUSE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes Ghostscript to read a character from ``/dev/tty``, rather than standard input, at the end of each page. This may be useful if input is coming from a pipe. + +.. note:: + + ``-dTTYPAUSE`` overrides ``-dNOPAUSE``. + + + +Device and output selection parameters +"""""""""""""""""""""""""""""""""""""""""""""" + +**-dNODISPLAY** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Initializes Ghostscript with a null device (a device that discards the output image) rather than the default device or the device selected with -sDEVICE=. This is usually useful only when running PostScript code whose purpose is to compute something rather than to produce an output image. + +**-sDEVICE=** *device* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Selects an alternate initial :ref:`output device<Selecting an output device>`. + +**-sOutputFile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Selects an alternate output file (or pipe) for the initial output device, as described above. + +**-d.IgnoreNumCopies=** *true* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Some devices implement support for "printing" multiple copies of the input document and some do not, usually based on whether it makes sense for a particular output format. This switch instructs all devices to ignore a request to print multiple copies, giving more consistent behaviour. + + +Deferred Page Rendering +"""""""""""""""""""""""""""""""""""""""""""""" + +Raster printers and image formats that can use the "command list" (clist) to store a representation of the page prior to rendering can use the ``--saved-pages=`` *string* on the command line for deferred rendering of pages. + +Pages that are saved instead of printed are retained until the list of saved pages is emptied by the flush command of the ``saved-pages=`` command string. + +Pages can be printed in reverse or normal order, or selected pages, including all even or all odd, and multiple collated copies can be produced. Since pages are saved until the flush command, pages can be printed multiple times, in any order. + +Refer to the :ref:`Using Saved Pages<SavedPages.htm>` document for details. + + + + +EPS parameters +"""""""""""""""""""""""""""""""""""""""""""""" + +**-dEPSCrop** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Crop an EPS file to the bounding box. This is useful when converting an EPS file to a bitmap. + + +**-dEPSFitPage** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Resize an EPS file to fit the page. This is useful for shrinking or enlarging an EPS file to fit the paper size when printing. + This option is also set by the ``-dFitPage`` option. + +**-dNOEPS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Prevent special processing of EPS files. This is useful when EPS files have incorrect Document Structuring Convention comments. + + + + +ICC color parameters +"""""""""""""""""""""""""""""""""""""""""""""" + +For details about the ICC controls see the document `GS9 Color Management`_. + + +**-sDefaultGrayProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with undefined device gray color spaces. If this is not set, the profile file name "default_gray.icc" will be used as the default. + +**-sDefaultRGBProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with undefined device RGB color spaces. If this is not set, the profile file name "default_rgb.icc" will be used as the default. + +**-sDefaultCMYKProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with undefined device CMYK color spaces. If this is not set, the profile file name "default_cmyk.icc" will be used as the default. + +**-sDeviceNProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Associate a :title:`devicen` color space contained in a PS or PDF document with an ICC profile. Note that neither PS nor PDF provide in-document ICC profile definitions for DeviceN color spaces. With this interface it is possible to provide this definition. The colorants tag order in the ICC profile defines the lay-down order of the inks associated with the profile. A windows-based tool for creating these source profiles is contained in ``./toolbin/color/icc_creator``. + +**-sOutputICCProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with the output device. Care should be taken to ensure that the number of colorants associated with the device is the same as the profile. If this is not set, an appropriate profile (i.e. one with the proper number of colorants) will be selected from those in the directory specified by ``ICCProfilesDir`` (see below). Note that if the output device is CMYK + spot colorants, a CMYK profile can be used to provide color management for the CMYK colorants only. In this case, spot colors will pass through unprocessed assuming the device supports those colorants. It is also possible for these devices to specify NCLR ICC profiles for output. + + +**-sICCOutputColors=** *"Cyan, Magenta, Yellow, Black, Orange, Violet"* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + For the psdcmyk and tiffsep separation devices, the device ICC profile can be an NCLR profile, which means something that includes non-traditional inks like Orange, Violet, etc. In this case, the list of the color names in the order that they exist in the profile must be provided with this command line option. Note that if a color name that is specified for the profile occurs also within the document (e.g. "Orange" above), then these color names will be associated with the same separation. Additional names beyond those of the ICC profile component count can be included. In this case, those components will be installed into the tiffsep or psdcmyk device list of colors, following the ICC profile colors. The number of spot colors (those that go beyond the standard CMYK colors) allowed by tiffsep or psdcmyk can be set using ``-dMaxSpots=#``. The default value for this is currently set to 10 (``GS_SOFT_MAX_SPOTS``). As an example consider the case where we wish to use a 6CLR ICC profile that includes Orange and Violet, but need the device to include a specialty color component such as Varnish, which does not appear in the document and is not handled by the 6CLR ICC profile. + + In addition, we desire to allow one more spot color of the document to come through to our device. For this case using ``-sICCOutputColors="Cyan, Magenta, Yellow, Black, Orange, Violet, Varnish" -dMaxSpots=4 -sOutputICCProfile=My_6CLR_Profile.icc`` would provide the desired outcome. Note that it is up to the device or through the use of ``-sNamedProfile`` (see below) to involve the setting of any values in the Varnish channel. However, if an All color value is encountered in the document, the Varnish component will have its value set as will the Orange and Violet values (Likewise if a spot color named Varnish is encountered in the document the Varnish component will be used for the values). The All value is typically used for placing registration targets on separations. Finally, note that if an NCLR ICC profile is specified and ``ICCOutputColors`` is not used, then a set of default names will be used for the extra colorants (non-CMYK) in the profile. These names are given as ``ICC_COLOR_N`` for the Nth non-CMYK channel. + +**-sProofProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Enable the specificiation of a proofing profile that will make the color management system link multiple profiles together to emulate the device defined by the proofing profile. See the document `GS9 Color Management`_ for details about this option. + +**-sDeviceLinkProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Define a device link profile. This profile is used following the output device profile. Care should be taken to ensure that the output device process color model is the same as the output color space for the device link profile. In addition, the color space of the ``OutputICCProfile`` should match the input color space of the device link profile. For example, the following would be a valid specification ``-sDEVICE=tiff32nc -sOutputICCProfile=srgb.icc -sDeviceLinkProfile=linkRGBtoCMYK.icc``. In this case, the output device's color model is CMYK (tiff32nc) and the colors are mapped through sRGB and through a devicelink profile that maps sRGB to CMYK values. See the document `GS9 Color Management`_ for details about this option. + + +**-sNamedProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Define a structure that is to be used by the color management module (CMM) to provide color management of named colors. While the ICC does define a named color format, this structure can in practice be much more general. Many developers wish to use their own proprietary-based format for spot color management. This command option is for developer use when an implementation for named color management is designed for the function gsicc_transform_named_color located in gsicccache.c . An example implementation is currently contained in the code for the handling of both Separation and DeviceN colors. For the general user this command option should really not be used. + + +**-sBlendColorProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + With the PDF transparency imaging model, a color space can be specified within which the color blending operations are to take place. Some files lack this specification, in which case the blending occurs in the output device's native color space. This dependency of blending color space on the device color model can be avoided by using the above command to force a specific color space in which to perform the blending. + +**-dColorAccuracy=** *0/1/2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the level of accuracy that should be used. A setting of 0 will result in less accurate color rendering compared to a setting of 2. However, the creation of a transformation will be faster at a setting of 0 compared to a setting of 2. Default setting is 2. + +**-dRenderIntent=** *0/1/2/3* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the rendering intent that should be used with the profile specified above by ``-sOutputICCProfile``. The options 0, 1, 2, and 3 correspond to the ICC intents of Perceptual, Colorimetric, Saturation, and Absolute Colorimetric. + +**-dBlackPtComp=** *0/1* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black point compensation should be used with the profile specified above by ``-sOutputICCProfile``. + +**-dKPreserve=** *0/1/2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black preservation should be used when mapping from CMYK to CMYK. When using littleCMS as the CMM, the code 0 corresponds to no preservation, 1 corresponds to the ``PRESERVE_K_ONLY`` approach described in the littleCMS documentation and 2 corresponds to the ``PRESERVE_K_PLANE`` approach. This is only valid when using littleCMS for color management. + +**-sVectorICCProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with the output device for vector-based graphics (e.g. Fill, Stroke operations). Care should be taken to ensure that the number of colorants associated with the device is the same as the profile. This can be used to obtain more saturated colors for graphics. + +**-dVectorIntent=** *0/1/2/3* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the rendering intent that should be used with vector-based graphic objects. The options are the same as specified for ``-dRenderIntent``. + +**-dVectorBlackPt=** *0/1* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black point compensation should be used for vector-based graphic objects. + +**-dVectorKPreserve=** *0/1/2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black preservation should be used when mapping from CMYK to CMYK for vector-based graphic objects. The options are the same as specified for ``-dKPreserve``. + +**-sImageICCProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with the output device for images. Care should be taken to ensure that the number of colorants associated with the device is the same as the profile. This can be used to obtain perceptually pleasing images. + +**-dImageIntent=** *0/1/2/3* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the rendering intent that should be used for images. + +**-dImageBlackPt=** *0/1* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black point compensation should be used with images. + + +**-dImageKPreserve=** *0/1/2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black preservation should be used when mapping from CMYK to CMYK for image objects. The options are the same as specified for ``-dKPreserve``. + +**-sTextICCProfile=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the ICC profile that will be associated with the output device for text. Care should be taken to ensure that the number of colorants associated with the device is the same as the profile. This can be used ensure K only text. + +**-dTextIntent=** *0/1/2/3* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set the rendering intent that should be used text objects. The options are the same as specified for ``-dRenderIntent``. + +**-dTextBlackPt=** *0/1* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black point compensation should be used with text objects. + +**-dTextKPreserve=** *0/1/2* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Specify if black preservation should be used when mapping from CMYK to CMYK for text objects. The options are the same as specified for ``-dKPreserve``. + +**-dOverrideICC** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Override any ICC profiles contained in the source document with the profiles specified by ``sDefaultGrayProfile``, ``sDefaultRGBProfile``, ``sDefaultCMYKProfile``. Note that if no profiles are specified for the default ``Device`` color spaces, then the system default profiles will be used. For detailed override control in the specification of source colors see ``-sSourceObjectICC``. + +**-sSourceObjectICC=** *filename* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option provides an extreme level of override control to specify the source color spaces and rendering intents to use with vector-based graphics, images and text for both RGB and CMYK source objects. The specification is made through a file that contains on a line a key name to specify the object type (e.g. ``Image_CMYK``) followed by an ICC profile file name, a rendering intent number (0 for perceptual, 1 for colorimetric, 2 for saturation, 3 for absolute colorimetric) and information for black point compensation, black preservation, and source ICC override. It is also possible to turn off color management for certain object types, use device link profiles for object types and do custom color replacements. An example file is given in ``./gs/toolbin/color/src_color/objsrc_profiles_example.txt``. Profiles to demonstrate this method of specification are also included in this folder. Note that if objects are colorimetrically specified through this mechanism other operations like ``-dImageIntent``, ``-dOverrideICC``, have no affect. Also see below the interaction with the ``-dDeviceGrayToK`` option. See further details in the document `GS9 Color Management`_. + + + +**-dDeviceGrayToK=** *true/false* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + By default, Ghostscript will map ``DeviceGray`` color spaces to pure K when the output device is CMYK based. This may not always be desired. In particular, it may be desired to map from the gray ICC profile specified by ``-sDefaultGrayProfile`` to the output device profile. To achieve this, one should specify ``-dDeviceGrayToK=false``. Note that this option may not have any effect in cases where ``SourceObjectICC`` settings are made for gray objects. In particular, if the gray objects in ``SourceObjectICC`` are set to None, which implies that ICC color management is not to be applied to these objects, then they are treated as ``DeviceGray`` and always mapped to K values in a CMYK target device, regardless of the settings of ``-dDeviceGrayToK`` (i.e. there is no color management). If instead, the gray objects in ``SourceObjectICC`` are set to a specific ICC profile, then they are no longer ``DeviceGray`` but are ICC colors. They will be color managed, regardless of the setting of ``-dDeviceGrayToK``. + +**-dUseFastColor=** *true/false* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This is used to avoid the use of ICC profiles for source colors. This includes those that are defined by ``DeviceGray``, ``DeviceRGB`` and ``DeviceCMYK`` definitions as well as ICC-based color spaces in the source document. With UseFastColor set to true, the traditional Postscript 255 minus operations are used to convert between RGB and CMYK with black generation and undercolor removal mappings. + +**-dSimulateOverprint=** *true/false* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option has been replaced by ``-dOverprint=`` + +**-dOverprint=** */enable | /disable | /simulate* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option provides control of overprinting. The default setting is */enable* which allows devices such as CMYK that can support overprint to leave planes unchanged under control of PostScript and PDF overprint settings. + + The */disable* setting ignores all overprint (and overprint mode) from the input. + + If */simulate* is set, then pages with overprint (or overprint mode) set for CMYK or Separation colors will be internally maintained and output to RGB or Gray devices. + +.. note:: + + Not all spot color overprint cases can be accurately simulated with a CMYK only device. For example, a case where you have a spot color overprinted with CMYK colors will be indistiguishable from a case where you have spot color equivalent CMYK colorants overprinted with CMYK colors, even though they may need to show significantly different overprint simulations. To obtain a full overprint simulation, use the */simulate* setting or the psdcmyk or tiffsep device, where the spot colors are kept in their own individual planes. + + +**-dUsePDFX3Profile=** *int* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + This option enables rendering with an output intent defined in the PDF source file. If this option is included in the command line, source device color values (e.g ``DeviceCMYK``, ``DeviceRGB``, or ``DeviceGray``) that match the color model of the output intent will be interpreted to be in the output intent color space. In addition, if the output device color model matches the output intent color model, then the destination ICC profile will be the output intent ICC profile. If there is a mismatch between the device color model and the output intent, the output intent profile will be used as a proofing profile, since that is the intended rendering. Note that a PDF document can have multiple rendering intents per the PDF specification. As such, with the option ``-dUsePDFX3Profile`` the first output intent encountered will be used. It is possible to specify a particular output intent where int is an integer (a value of 0 is the same as not specifying a number). Probing of the output intents for a particular file is possible using extractICCprofiles.ps in ``./gs/toolbin``. Finally, note that the ICC profile member entry is an option in the output intent dictionary. In these cases, the output intent specifies a registry and a standard profile (e.g. Fogra39). Ghostscript will not make use of these output intents. Instead, if desired, these standard profiles should be used with the commands specified above (e.g. ``-sOutputICCProfile``). + +**-sUseOutputIntent=** *string* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Like ``-dUsePDFX3Profile`` above, this option enables rendering with an output intent defined in the PDF source file. + This option behaves the same way as the ``-dUsePDFX3Profile``, but the selection criteria are different. Because its possible (as of PDF 2.0) for each page to have a different array, its not sufficient just to supply an array index, as the same profile might potentially be at different indices in each array. + + Instead this option takes a string, which is first compared against the ``OutputConditionIdentifier`` in each ``OutputIntent`` in the array. If the ``OutputConditionIdentifier`` is not a standard identifier then it should be ``Custom`` and the ``UseOutputIntent`` string will be matched against the value of the ``Info`` key instead. If the ``OutputConditionIdentifier`` or ``Info`` matches the value of ``UseOuttpuIntent``, then that ``OutputIntent`` is selected if the ``OutputIntent`` contains a ``DestOutputProfile`` key. + + +**-sICCProfilesDir=** *path* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Set a directory in which to search for the above profiles. The directory path must end with a file system delimiter. + If the user doesn't use the ``-sICCProfilesDir=`` command line option, Ghostscript creates a default value for it by looking on the directory paths explained in `How Ghostscript finds files`_. If the current directory is the first path a test is made for the ``iccprofiles`` directory. Next, the remaining paths with the string Resource in it are tested. The prefix up to the path separator character preceding the string Resource, concatenated with the string ``iccprofiles`` is used and if this exists, then this path will be used for ``ICCProfilesDir``. + + Note that if the build is performed with ``COMPILE_INITS=1``, then the profiles contained in ``gs/iccprofiles`` will be placed in the ROM file system. If a directory is specified on the command line using ``-sICCProfilesDir=``, that directory is searched before the ``iccprofiles/`` directory of the ROM file system is searched. + +.. note :: + + A note for Windows users, Artifex recommends the use of the forward slash delimiter due to the special interpretation of ``\"`` by the Microsoft C startup code. See `Parsing C Command-Line Arguments`_ for more information. + + + +Other parameters +""""""""""""""""""""""" + +**-dFILTERIMAGE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + If set, this will ignore all images in the input (in this context image means a bitmap), these will therefore not be rendered. + +**-dFILTERTEXT** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + If set, this will ignore all text in the input (just because it looks like text doesn't mean it is, it might be an image), text will therefore not be rendered. + +**-dFILTERVECTOR** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + If set, this will ignore anything which is neither text nor an image. + +**-dDELAYBIND** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes bind to remember all its invocations, but not actually execute them until the :ref:`.bindnow<Language_BindNow>` procedure is called. Useful only for certain specialized packages like pstotext that redefine operators. See the documentation for :ref:`.bindnow<Language_BindNow>` for more information on using this feature. + +**-dDOPDFMARKS** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Causes pdfmark to be called for bookmarks, annotations, links and cropbox when processing PDF files. Normally, ``pdfmark`` is only called for these types for PostScript files or when the output device requests it (e.g. :title:`pdfwrite` device). + + +**-dJOBSERVER** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Define ``\004 (^D)`` to start a new encapsulated job used for compatibility with Adobe PS Interpreters that ordinarily run under a job server. The ``-dNOOUTERSAVE`` switch is ignored if ``-dJOBSERVER`` is specified since job servers always execute the input PostScript under a save level, although the ``exitserver`` operator can be used to escape from the encapsulated job and execute as if the ``-dNOOUTERSAVE`` was specified. + This also requires that the input be from stdin, otherwise an error will result (Error: ``/invalidrestore in --restore--``). + + Example usage is: + +.. code-block :: bash + + gs ... -dJOBSERVER - < inputfile.ps + + Or: + +.. code-block :: bash + + cat inputfile.ps | gs ... -dJOBSERVER - + +.. note:: + + The ``^D`` does not result in an end-of-file action on stdin as it may on some PostScript printers that rely on TBCP (Tagged Binary Communication Protocol) to cause an out-of-band ``^D`` to signal EOF in a stream input data. This means that direct file actions on ``stdin`` such as ``flushfile`` and ``closefile`` will affect processing of data beyond the ``^D`` in the stream. + +**-dNOCACHE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Disables character caching. Useful only for debugging. + +**-dNOGC** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Suppresses the initial automatic enabling of the garbage collector in Level 2 systems. (The ``vmreclaim`` operator is not disabled.) Useful only for debugging. + +**-dNOOUTERSAVE** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Suppresses the initial save that is used for compatibility with Adobe PS Interpreters that ordinarily run under a job server. If a job server is going to be used to set up the outermost save level, then ``-dNOOUTERSAVE`` should be used so that the restore between jobs will restore global VM as expected. + +**-dNOSAFER** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Equivalent to ``-dDELAYSAFER``. + + This flag disables ``SAFER`` mode until the ``.setsafe`` procedure is run. This is intended for clients or scripts that cannot operate in ``SAFER`` mode. If Ghostscript is started with ``-dNOSAFER`` or ``-dDELAYSAFER``, PostScript programs are allowed to read, write, rename or delete any files in the system that are not protected by operating system permissions. + + This mode should be used with caution, and ``.setsafe`` should be run prior to running any PostScript file with unknown contents. + + + + +.. _Use Safer: +.. _dSAFER: + + +**-dSAFER** +^^^^^^^^^^^^ + + .. important :: + + Ghostscript now (as of 9.50) defaults to ``SAFER`` being active. + + Enables access controls on files. Access controls fall into three categories, files from which Ghostscript is permitted to read, ones to which it is permitted to write, and ones over which it has "control" (i.e. delete/rename). These access controls apply to all files accessed via Ghostscript's internal interface to the C library file handling. Whilst we have taken considerable pains to ensure that all the code we maintain (as well as the so called "contrib" devices, that are devices included in our release packages, but not strictly maintained by the Ghostscript development team) uses this interface, we have no control over thirdparty code. + + + This is an entirely new implementation of ``SAFER`` for Ghostscript versions 9.50 and later. Earlier versions (see :ref:`-dOLDSAFER<dOLDSAFER>`) relied on storing the file permission lists in Postscript VM (Virtual Memory), and only applied file access permissions to the Postscript file related operators. It relied on restricting the function of setpagedevice to avoid the device code from being manipulated into opening arbitrary files. The application of the file permissions was done within the internal context of the Postscript interpreter, and some other aspects of the Postscript restrictions were applied in the Postscript environment. With so many of the feature's capabilities relying on the Postscript context and environment, by using other (Ghostscript specific) features maliciously, the restrictions could be overridden. + + Whilst the path storage and application of the permissions is implemented entirely in C, it is still possible for Postscript to add and remove paths from the permissions lists (see .addcontrolpath) until such time as the access controls are enabled (see :ref:`.activatepathcontrol<Language_ActivateControlPath>`), any call to :ref:`.addcontrolpath<Language_AddControlPath>` after :ref:`.activatepathcontrol<Language_ActivateControlPath>` will result in a ``Fatal`` error causing the interpreter to immediately exit. + + An incompatibility exists between the pre-9.50 and 9.50 and later ``SAFER``. By removing storage and application entirely from the Postscript language environment and internal context, ``SAFER`` is no longer affected by Postscript save/restore operations. Previously, it was possible to do the equivalent of: + + + .. code-block :: bash + + save + .setsafe + Postscript ops + restore + + In that sequence, the Postscript ops would run with ``SAFER`` protection but after the restore, ``SAFER`` would no longer be in force. This is no longer the case. After the call to ``.setsafe`` the file controls are in force until the interpreter exits. As the 9.50 and later implementation no longer restricts the operation of ``setpagedevice``, and because this capability is extremely rarely used, we feel the improvement in security warrants the small reduction in flexibility. + + Path matching is very simple: it is case sensitive, and we do not implement full featured "globbing" or regular expression matching (such complexity would significantly and negatively impact performance). Further, the string parameter(s) passed to the ``--permit-file-*`` option must exactly match the string(s) used to reference the file(s): for example, you cannot use an absolute path to grant permission, and then a relative path to reference the file (or vice versa) - the path match will fail. Similarly, you cannot grant permission through one symlink, and then reference a file directly, or through an alternative symlink - again, the matching will fail. + + + The following cases are handled: + + .. code-block :: bash + + "/path/to/file" + + Permits access only to the file: "/path/to/file" + + .. code-block :: bash + + "/path/to/directory/" + + Permits access to any file in, and only in, the directory: "/path/to/directory" + + .. code-block :: bash + + "/path/to/directory/*" + + Permits access to any file in the directory: "/path/to/directory" and any child of that directory. + + + .. important :: Note for Windows Users + + The file/path pattern matching is case sensitive, even on Windows. This is a change in behaviour compared to the old code which, on Windows, was case insensitive. This is in recognition of changes in Windows behaviour, in that it now supports (although does not enforce) case sensitivity. + + + Four command line parameters permit explicit control of the paths included in the access control lists: + + .. code-block :: bash + + --permit-file-read=pathlist + + Adds a path, or list of paths, to the "permit read" list. A list of paths is a series of paths separated by the appropriate path list separator for your platform (for example, on Unix-like systems it is ":" and on MS Windows it is ";"). + + .. code-block :: bash + + --permit-file-write=pathlist + + Adds a path, or list of paths, to the "permit write" list. A list of paths is a series of paths separated by the appropriate path list separator for your platform (for example, on Unix-like systems it is ":" and on MS Windows it is ";"). + + .. code-block :: bash + + --permit-file-control=pathlist + + Adds a path, or list of paths, to the "permit control" list. A list of paths is a series of paths separated by the appropriate path list separator for your platform (for example, on Unix-like systems it is ":" and on MS Windows it is ";"). + + .. code-block :: bash + + --permit-file-all=pathlist + + Adds a path, or list of paths, to the all the above lists. A list of paths is a series of paths separated by the appropriate path list separator for your platform (for example, on Unix-like systems it is ":" and on MS Windows it is ";"). + + '``*``' may be used as a wildcard in the above paths to mean "any character other than the directory separator. Do not use two or more ``*``'s without intervening characters. + + Finally, paths supplied on the command line (such as those in ``-I``, ``-sFONTPATH`` parameters) are added to the permitted reading list. Similarly, paths read during initialisation from ``Fontmap``, ``cidfmap``, and the platform specific font file enumeration (e.g. ``fontconfig`` on Unix systems) are automatically added to the permit read lists. + + + + +.. _dOLDSAFER: + +**-dOLDSAFER** +^^^^^^^^^^^^^^^^^^ + + .. important :: This enables deprecated code which will shortly be removed. + + Used in combination with ``-dSAFER`` (or ``.setsafe``) enables the pre-9.50 ``SAFER`` implementation. It is included (for now) in case any users find a case where the 9.50 and later ``SAFER`` does not work for them. It means such users can keep working until we have assessed the issue, and distributed a solution. + + Disables the ``deletefile`` and ``renamefile`` operators, and the ability to open piped commands (``%pipe%cmd``) at all. Only ``%stdout`` and ``%stderr`` can be opened for writing. Disables reading of files other than ``%stdin``, those given as a command line argument, or those contained on one of the paths given by ``LIBPATH`` and ``FONTPATH`` and specified by the system params ``/FontResourceDir`` and ``/GenericResourceDir``. + + This mode also sets the :ref:`.LockSafetyParams<Language_LockSafetyParams>` parameter of the default device, or the device specified with the ``-sDEVICE=`` switch to protect against programs that attempt to write to files using the ``OutputFile`` device parameter. Note that since the device parameters specified on the command line (including ``OutputFile``) are set prior to ``SAFER`` mode, the ``-sOutputFile=...`` on the command line is unrestricted. + + ``SAFER`` mode also prevents changing the ``/GenericResourceDir``, ``/FontResourceDir`` and either the ``/SystemParamsPassword`` or the ``/StartJobPassword``. + + When running ``-dNOSAFER`` it is possible to perform a save, followed by ``.setsafe``, execute a file or procedure in ``SAFER`` mode, then use restore to return to ``NOSAFER`` mode. It is possible that a crafted foreign file could restore back to a point when ``NOSAFER`` was in operation. + +**-dPreBandThreshold=** *true/false* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + If the target device is a halftone device, then images that are normally stored in the command list during banded output will be halftoned during the command list writing phase, if the resulting image will result in a smaller command list. The decision to halftone depends upon the output and source resolution as well as the output and source color space. + +**-dWRITESYSTEMDICT** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Leaves systemdict writable. This is necessary when running special utility programs such as ``font2c`` and ``pcharstr``, which must bypass normal PostScript access protection. + + +.. _Use_Improving Performance: + +Improving performance +---------------------------------------------- + +Ghostscript attempts to find an optimum balance between speed and memory consumption, but there are some cases in which you may get a very large speedup by telling Ghostscript to use more memory. + +Please note that this discussion relates to devices which produce a bitmap format as the output. These parameters have no effect on the vector devices, such as :title:`pdfwrite`. + +- For raster printers and image format (jpeg*, tiff*, png* ...) devices, performance can be 'tuned' by adjusting some of the parameters related to banding (clist) options (refer to: :ref:`Banding Parameters<Language_BandingParams>`). + +- All devices may use a display list ("clist") and use banding when rendering PDF 1.4 transparency. This prevents allocation of excessively large amounts of memory for the transparency buffer stack. The ``-dMaxBitmap=`` option is used to control when to use the display list, and the other banding parameters mentioned above control the band size. + + In general, page buffer mode is faster than banded/clist mode (a full page buffer is used when ``-dMaxBitmap=#`` is large enough for the entire raster image) since there is no need to write, then interpret the clist data. + + On a multi-core system where multiple threads can be dispatched to individual processors/cores, banding mode may provide higher performance since ``-dNumRenderingThreads=#`` can be used to take advantage of more than one CPU core when rendering the clist. The number of threads should generally be set to the number of available processor cores for best throughput. + + In general, larger ``-dBufferSpace=#`` values provide slightly higher performance since the per-band overhead is reduced. + +- If you are using X Windows, setting the ``-dMaxBitmap=`` parameter described in `X device parameters`_ may dramatically improve performance on files that have a lot of bitmap images. + +- With some PDF files, or if you are using Chinese, Japanese, or other fonts with very large character sets, adding the following sequence of switches before the first file name may dramatically improve performance at the cost of an additional memory. For example, to allow use of 30Mb of extra RAM use: ``-c 30000000 setvmthreshold -f``. + + This can also be useful in processing large documents when using a high-level (vector) output device (like :title:`pdfwrite`) that maintains significant internal state. + +- For pattern tiles that are very large, Ghostscript uses an internal display list (memory based clist), but this can slow things down. The current default threshold is 8Mb -- pattern tiles larger than this will be cached as clist rather than bitmap tiles. The parameter ``-dMaxPatternBitmap=#`` can be used to adjust this threshold, smaller to reduce memory requirements and larger to avoid performance impacts due to clist based pattern handling. + + For example, ``-dMaxPatternBitmap=200000`` will use clist based patterns for pattern tiles larger than 200,000 bytes. + + + +Summary of environment variables +---------------------------------------------- + +GS, GSC (MS Windows only) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Specify the names of the Ghostscript executables. ``GS`` brings up a new typein window and possibly a graphics window; GSC uses the DOS console. If these are not set, ``GS`` defaults to ``gswin32``, and ``GSC`` defaults to ``gswin32c``. + +GS_DEVICE +~~~~~~~~~~~~~~ + Defines the default output device. This overrides the compiled-in default, but is overridden by any command line setting. + +GS_FONTPATH +~~~~~~~~~~~~~~ + Specifies a list of directories to scan for fonts if a font requested can't be found anywhere on the search path. + +GS_LIB +~~~~~~~~~~ + Provides a search path for initialization files and fonts. + +GS_OPTIONS +~~~~~~~~~~~~~ + Defines a list of command-line arguments to be processed before the ones actually specified on the command line. For example, setting ``GS_DEVICE`` to ``XYZ`` is equivalent to setting ``GS_OPTIONS`` to ``-sDEVICE=XYZ``. The contents of ``GS_OPTIONS`` are not limited to switches; they may include actual file names or even "@file" arguments. + +TEMP, TMPDIR +~~~~~~~~~~~~~~~~ + Defines a directory name for temporary files. If both ``TEMP`` and ``TMPDIR`` are defined, ``TMPDIR`` takes precedence. + + +.. _Use_Debugging: + + +Debugging +---------------------------------------------- + +The information here describing is probably interesting only to developers. + +Debug switches +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are several debugging switches that are detected by the interpreter. These switches are available whether or not Ghostscript was built with the ``DEBUG`` macro defined to the compiler (refer to building a debugging configuration). + +Previous to 8.10, there was a single ``DEBUG`` flag, enabled with ``-dDEBUG`` on the command line. Now there are several debugging flags to allow more selective debugging information to be printed containing only what is needed to investigate particular areas. For backward compatibilty, the ``-dDEBUG`` option will set all of the subset switches. + + +.. list-table:: + :widths: 50 50 + + * - -dCCFONTDEBUG + - Compiled Fonts + * - -dCFFDEBUG + - CFF Fonts + * - -dCMAPDEBUG + - CMAP + * - -dDOCIEDEBUG + - CIE color + * - -dEPSDEBUG + - EPS handling + * - -dFAPIDEBUG + - Font API + * - -dINITDEBUG + - Initialization + * - -dPDFDEBUG + - PDF Interpreter + * - -dPDFWRDEBUG + - PDF Writer + * - -dSETPDDEBUG + - setpagedevice + * - -dSTRESDEBUG + - Static Resources + * - -dTTFDEBUG + - TTF Fonts + * - -dVGIFDEBUG + - ViewGIF + * - -dVJPGDEBUG + - ViewJPEG + +The PDF interpreter normally tries to repair, or ignore, all problems encountered in PDF files. Setting ``-dPDFSTOPONERROR`` instead causes the interpreter to signal an error and stop processing the PDF file, instead of printing a warning. + +The ``-dPDFSTOPONWARNING`` switch behaves the same, but will stop if a condition which would normally merit a warning (instead of an error) is encountered. Note that setting ``-dPDFSTOPONWARNING`` also sets ``-dPDFSTOPONERROR``. + +The ``-Z`` and ``-T`` switches apply only if the interpreter was :ref:`built for a debugging configuration<Make_Debugging>`. In the table below, the first column is a debugging switch, the second is an equivalent switch (if any) and the third is its usage. + + + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Switch + - Equivalent switch + - Usage + * - ``0`` + - + - garbage collector, minimal detail + * - ``1`` + - + - type 1 and type 42 font interpreter + * - ``2`` + - + - curve subdivider/rasterizer + * - + - ``3`` + - curve subdivider/rasterizer, detail + * - ``4`` + - + - garbage collector (strings) + * - + - ``5`` + - garbage collector (strings, detail) + * - ``6`` + - + - garbage collector (clumps, roots) + * - + - ``7`` + - garbage collector (objects) + * - + - ``8`` + - garbage collector (refs) + * - + - ``9`` + - garbage collector (pointers) + * - ``a`` + - + - allocator (large blocks only) + * - + - ``A`` + - allocator (all calls) + * - ``b`` + - + - bitmap image processor + * - + - ``B`` + - bitmap images, detail + * - ``c`` + - + - color/halftone mapper + * - ``d`` + - + - dictionary put/undef + * - + - ``D`` + - dictionary lookups + * - ``e`` + - + - external (OS-related) calls + * - ``f`` + - + - fill algorithm (summary) + * - + - ``F`` + - fill algorithm (detail) + * - ``g`` + - + - gsave/grestore[all] + * - ``h`` + - + - halftone renderer + * - + - ``H`` + - halftones, every pixel + * - ``i`` + - + - interpreter, just names + * - + - ``I`` + - interpreter, everything + * - ``j`` + - + - (Japanese) composite fonts + * - ``k`` + - + - character cache and xfonts + * - + - ``K`` + - character cache, every access + * - ``l`` + - + - command lists, bands + * - + - ``L`` + - command lists, everything + * - ``m`` + - + - makefont and font cache + * - ``n`` + - + - name lookup (new names only) + * - ``o`` + - + - outliner (stroke) + * - + - ``O`` + - stroke detail + * - ``p`` + - + - band list paths + * - + - ``P`` + - all paths + * - ``q`` + - + - clipping + * - ``r`` + - + - arc renderer + * - ``s`` + - + - streams + * - + - ``S`` + - scanner + * - ``t`` + - + - tiling algorithm + * - ``u`` + - + - undo saver (for save/restore), finalization + * - + - ``U`` + - undo saver, more detail + * - ``v`` + - + - compositors: alpha/transparency/overprint/rop + * - + - ``V`` + - compositors: alpha/transparency/overprint/rop, more detail + * - ``w`` + - + - compression encoder/decoder + * - ``x`` + - + - transformations + * - ``y`` + - + - Type 1 hints + * - + - ``Y`` + - Type 1 hints, every access + * - ``z`` + - + - trapezoid fill + * - ``#`` + - + - operator error returns + * - ``%`` + - + - externally processed comments + * - ``*`` + - + - image and RasterOp parameters + * - ``:`` + - + - command list and allocator/time summary + * - ``~`` + - + - math functions and Functions + * - ``'`` + - + - contexts, create/destroy + * - + - ``"`` + - contexts, every operation + * - ``^`` + - + - reference counting + * - ``_`` + - + - high-level (vector) output + * - ``!`` + - + - Postscript operator names (this option is available only when Ghostscript is compiled with a predefined macro DEBUG_TRACE_PS_OPERATORS) + * - ``|`` + - + - (reserved for experimental code) + + +The following switch affects what is printed, but does not select specific items for printing: + + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Switch + - Equivalent switch + - Usage + * - ``/`` + - + - include file name and line number on all trace output + + +These switches select debugging options other than what should be printed: + +.. We need to add a special piece of raw HTML to print a dingle backtick character in RST + +.. |bt| raw:: html + + <code class="code docutils literal notranslate">`</code> + + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Switch + - Equivalent switch + - Usage + * - ``$`` + - + - set unused parts of object references to identifiable garbage values + * - ``+`` + - + - use minimum-size stack blocks + * - ``,`` + - + - don't use path-based banding + * - |bt| + - + - don't use high-level banded images + * - ``?`` + - + - validate pointers before, during and after garbage collection, also before and after save and restore; also make other allocator validity checks + * - ``@`` + - + - fill newly allocated, garbage-collected, and freed storage with a marker (a1, c1, and f1 respectively) + * - ``f`` + - + - the filling algorithm with characters + * - + - ``F`` + - the filling algorithm with non-character paths + * - ``h`` + - + - the Type 1 hinter + * - ``s`` + - + - the shading algorithm + * - + - ``S`` + - the stroking algorithm + + +Switches used in debugging +""""""""""""""""""""""""""" + + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Switch + - Description + * - ``-Bsize`` + - Run all subsequent files named on the command line (except for ``-F``) through the ``run_string`` interface, using a buffer of size bytes. + * - ``-B-`` + - Turn off ``-B``: run subsequent files (except for ``-F``) directly in the normal way. + * - ``-Ffile`` + - Execute the file with ``-B1`` temporarily in effect + * - ``-Kn`` + - Limit the total amount of memory that the interpreter can have allocated at any one time to nK bytes. n is a positive decimal integer. + * - ``-Mn`` + - Force the interpreter's allocator to acquire additional memory in units of nK bytes, rather than the default 20K. + + n is a positive decimal integer, on 16-bit systems no greater than 63. + * - ``-Nn`` + - Allocate space for nK names, rather than the default (normally 64K). + + n may be greater than 64 only if ``EXTEND_NAMES`` was defined (in ``inameidx.h``) when the interpreter was compiled. + * - ``-Zxxx`` + + ``-Z-xxx`` + - Turn debugging printout on (off). Each of the xxx characters selects an option. + + Case is significant: "a" and "A" have different meanings. + * - ``-Txxx`` + + ``-T-xxx`` + - Turn Visual Trace on (off). Each of the xxx characters selects an option. + + Case is significant: "f" and "F" have different meanings. + + + +In addition, calling Ghostscript with ``--debug`` will list all the currently defined (non visual trace) debugging flags, both in their short form (as listed above for use with ``-Z``) and in a long form, which can be used as in: ``--debug=tiling,alloc``. All the short form flags for ``-Z`` have an equivalent long form. Future flags may be added with a long form only (due to all the short form flags being used already). + + + + +Visual Trace +~~~~~~~~~~~~~~~~~~ + +Visual Trace allows to view internal Ghostscript data in a graphical form while execution of C code. Special :ref:`instructions<Lib_VisualTrace>` to be inserted into C code for generating the output. Client application rasterizes it into a window. + +Currently the rasterization is implemented for Windows only, in clients ``gswin32.exe`` and ``gswin32c.exe``. They open Visual Trace window when graphical debug output appears, ``-T`` :ref:`switch<Debug switches>` is set, and Ghostscript was :ref:`built<Make_Debugging>` with ``DEBUG`` option. + +There are two important incompletenesses of the implementation : + +#. The graphical output uses a hardcoded scale. An advanced client would provide a scale option via user interface. + +#. Breaks are not implemented in the client. If you need a step-by-step view, you should use an interactive C debugger to delay execution at breakpoints. + + +.. _Known Paper Sizes: + + +Appendix: Paper sizes known to Ghostscript +---------------------------------------------- + +The paper sizes known to Ghostscript are defined at the beginning of the initialization file ``gs_statd.ps``; see the comments there for more details about the definitions. The table here lists them by name and size. ``gs_statd.ps`` defines their sizes exactly in points, and the dimensions in inches (at 72 points per inch) and centimeters shown in the table are derived from those, rounded to the nearest 0.1 unit. A guide to international paper sizes can be found at `papersizes.org`_. + + +U.S. standard +~~~~~~~~~~~~~~~~ + +.. list-table:: + :widths: 20 20 20 20 20 + :header-rows: 2 + + * - Name + - Inches + - mm + - Points + - Notes + * - + - W x H + - W x H + - W x H + - + * - 11 x 17 + - 11.0 x 17.0 + - 279 x 432 + - 792 x 1224 + - 11×17in portrait + * - ledger + - 17.0 x 11.0 + - 432 x 279 + - 1224 x 792 + - 11×17in landscape + * - legal + - 8.5 x 14.0 + - 216 x 356 + - 612 x 1008 + - + * - letter + - 8.5 x 11.0 + - 216 x 279 + - 612 x 792 + - + * - letter small + - 8.5 x 11.0 + - 216 x 279 + - 612 x 792 + - + * - archA + - 9.0 x 12.0 + - 229 x 305 + - 648 x 864 + - + * - archB + - 12.0 x 18.0 + - 305 x 457 + - 864 x 1296 + - + * - archC + - 18.0 x 24.0 + - 457 x 610 + - 1296 x 1728 + - + * - archD + - 24.0 x 36.0 + - 610 x 914 + - 1728 x 2592 + - + * - archE + - 36.0 x 48.0 + - 914 x 1219 + - 2592 x 3456 + - + +ISO standard +~~~~~~~~~~~~~~~~ + + +.. list-table:: + :widths: 20 20 20 20 20 + :header-rows: 2 + + * - Name + - Inches + - mm + - Points + - Notes + * - + - W x H + - W x H + - W x H + - + * - a0 + - 33.1 x 46.8 + - 841 x 1189 + - 2384 x 3370 + - + * - a1 + - 23.4 x 33.1 + - 594 x 841 + - 1684 x 2384 + - + * - a2 + - 16.5 x 23.4 + - 420 x 594 + - 1191 x 1684 + - + * - a3 + - 11.7 x 16.5 + - 297 x 420 + - 842 x 1191 + - + * - a4 + - 8.3 x 11.7 + - 210 x 297 + - 595 x 842 + - + * - a4small + - 8.3 x 11.7 + - 210 x 297 + - 595 x 842 + - + * - a5 + - 5.8 x 8.3 + - 148 x 210 + - 420 x 595 + - + * - a6 + - 4.1 x 5.8 + - 105 x 148 + - 297 x 420 + - + * - a7 + - 2.9 x 4.1 + - 74 x 105 + - 210 x 297 + - + * - a8 + - 2.1 x 2.9 + - 52 x 74 + - 148 x 210 + - + * - a9 + - 1.5 x 2.1 + - 37 x 52 + - 105 x 148 + - + * - a10 + - 1.0 x 1.5 + - 26 x 37 + - 73 x 105 + - + * - isob0 + - 39.4 x 55.7 + - 1000 x 1414 + - 2835 x 4008 + - + * - isob1 + - 27.8 x 39.4 + - 707 x 1000 + - 2004 x 2835 + - + * - isob2 + - 19.7 x 27.8 + - 500 x 707 + - 1417 x 2004 + - + * - isob3 + - 13.9 x 19.7 + - 353 x 500 + - 1001 x 1417 + - + * - isob4 + - 9.8 x 13.9 + - 250 x 353 + - 709 x 1001 + - + * - isob5 + - 6.9 x 9.8 + - 176 x 250 + - 499 x 709 + - + * - isob6 + - 4.9 x 6.9 + - 125 x 176 + - 354 x 499 + - + * - c0 + - 36.1 x 51.1 + - 917 x 1297 + - 2599 x 3677 + - + * - c1 + - 25.5 x 36.1 + - 648 x 917 + - 1837 x 2599 + - + * - c2 + - 18.0 x 25.5 + - 458 x 648 + - 1298 x 1837 + - + * - c3 + - 12.8 x 18.0 + - 324 x 458 + - 918 x 1298 + - + * - c4 + - 9.0 x 12.8 + - 229 x 324 + - 649 x 918 + - + * - c5 + - 6.4 x 9.0 + - 162 x 229 + - 459 x 649 + - + * - c6 + - 4.5 x 6.4 + - 114 x 162 + - 323 x 459 + - + + + +JIS standard +~~~~~~~~~~~~~~~~ + +.. list-table:: + :widths: 20 20 20 + :header-rows: 2 + + * - Name + - mm + - Notes + * - + - W x H + - + * - jisb0 + - 1030 x 1456 + - + * - jisb1 + - 728 x 1030 + - + * - jisb2 + - 515 x 728 + - + * - jisb + - 364 x 515 + - + * - jisb4 + - 257 x 364 + - + * - jisb5 + - 182 x 257 + - + * - jisb6 + - 128 x 182 + - + + + +ISO/JIS switchable +~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :widths: 20 + :header-rows: 1 + + * - Name + * - b0 + * - b1 + * - b2 + * - b3 + * - b4 + * - b5 + +.. note:: + + Initially the B paper sizes are the ISO sizes, e.g., **b0** is the same as **isob0**. Running the file ``lib/jispaper.ps`` makes the B paper sizes be the JIS sizes, e.g., **b0** becomes the same as **jisb0**. + + + +Other +~~~~~~~~~~~ + +.. list-table:: + :widths: 20 20 20 20 20 + :header-rows: 2 + + * - Name + - Inches + - mm + - Points + - Notes + * - + - W x H + - W x H + - W x H + - + * - flsa + - 8.5 x 13.0 + - 216 x 330 + - 612 x 936 + - U.S. foolscap + * - flse + - 8.5 x 13.0 + - 216 x 330 + - 612 x 936 + - European foolscap + * - halfletter + - 5.5 x 8.5 + - 140 x 216 + - 396 x 612 + - + * - hagaki + - 3.9 x 5.8 + - 100 x 148 + - 283 x 420 + - Japanese postcard + + +.. External links + + + +.. _GS9 Color Management: https://ghostscript.com/doc/current/GS9_Color_Management.pdf +.. _Parsing C Command-Line Arguments: http://msdn.microsoft.com/en-us/library/a1y7w461.aspx +.. _papersizes.org: https://www.papersizes.org/ + + + +.. include:: footer.rst + diff --git a/doc/src/VectorDevices.rst b/doc/src/VectorDevices.rst new file mode 100644 index 00000000..aa082d5c --- /dev/null +++ b/doc/src/VectorDevices.rst @@ -0,0 +1,1303 @@ +.. title:: High Level Devices + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _VectorDevices.htm: + + +High Level Devices +=================================== + + +High level devices are Ghostscript output devices which do not render to a raster, in general they produce 'vector' as opposed to bitmap output. Such devices currently include: :title:`pdfwrite`, :title:`ps2write`, :title:`eps2write`, :title:`txtwrite`, :title:`xpswrite`, :title:`pxlmono`, :title:`pxlcolor` and :title:`docxwrite`. + +Although these devices produce output which is not a raster, they still work in the same general fashion as all Ghostscript devices. The input (PostScript, PDF, XPS, PCL or PXL) is handled by an appropriate interpreter, the interpreter processes the input and produces from it a sequence of drawing 'primitives' which are handed to the device. The device decides whether to handle the primitive itself, or call upon the graphics library to render the primitive to the final raster. + +Primitives are quite low level graphics operations; as an example consider the PDF sequence ``'0 0 100 100 re f'``. This constructs a rectangle with the bottom left corner at 0,0 which is 100 units wide by 100 units high, and fills it with the current color. A lower level implementation using only primitives would first move the current point to 0,0, then construct a line to 0,100, then a line to 100,100, a line to 100, 0 and finally a line back to 0,0. It would then fill the result. + +Obviously that's a simple example but it serves to demonstrate the point. + +Now the raster devices all call the graphics library to process primitives (though they may choose to take some action first) and render the result to a bitmap. The high level devices instead reassemble the primitives back into high level page description and write the result to a file. This means that the output, while it should be visually the same as the input (because it makes the same marks), is not the same as the original input, even if the output Page Description Language is the same as the input one was (eg PDF to PDF). + +Why is this important? Firstly because the description of the page won't be the same, if your workflow relies upon (for example) finding rectangles in the description then it might not work after it has been processed by a high level device, as the rectangles may all have turned into lengthy path descriptions. + +In addition, any part of the original input which does not actually make marks on the page (such as hyperlinks, bookmarks, comments etc) will normally not be present in the output, even if the output is the same format. In general the PDF interpreter and the PDF output device (:title:`pdfwrite`) try to preserve the non-marking information from the input, but some kinds of content are not carried across, in particular comments are not preserved. + +We often hear from users that they are 'splitting' PDF files, or 'modifying' them, or converting them to PDF/A, and it's important to realize that this is not what's happening. Instead, a new PDF file is being created, which should look the same as the original, but the actual insides of the PDF file are not the same as the original. This may not be a problem, but if it's important to keep the original contents, then you need to use a different tool (we'd suggest MuPDF_, also available from Artifex). Of course, if the intention is to produce a modified PDF file (for example, reducing the resolution of images, or changing the colour space), then clearly you cannot keep the original contents unchanged, and :title:`pdfwrite` performs these tasks well. + + + +PCL-XL (PXL) +-------------- + +The :title:`pxlmono` and :title:`pxlcolor` devices output HP PCL-XL, a graphic language understood by many recent laser printers. + +Options +~~~~~~~~~~~~ + + +``-dCompressMode=1 | 2 | 3 (default is 1)`` + Set the compression algorithm used for bitmap graphics. RLE=1, JPEG=2, DeltaRow=3. When JPEG=2 is on, it is applied only to full-color images; indexed-color graphics and masks continues to be compressed with RLE. + + + +Text output +-------------- + +The :title:`txtwrite` device will output the text contained in the original document as Unicode. + +Options +~~~~~~~~~~~~ + +``-dTextFormat=0 | 1 | 2 | 3 | 4 (default is 3)`` + Format 0 is intended for use by developers and outputs XML-escaped Unicode along with information regarding the format of the text (position, font name, point size, etc). The XML output is the same format as the MuPDF output, but no additional processing is performed on the content, so no block detection. + + Format 1 uses the same XML output format, but attempts similar processing to MuPDF, and will output blocks of text. Note the algorithm used is not the same as the MuPDF code, and so the results will not be identical. + + Format 2 outputs Unicode (UCS2) text (with a Byte Order Mark) which approximates the layout of the text in the original document. + + Format 3 is the same as format 2, but the text is encoded in UTF-8. + + Format 4 is internal format similar to Format 0 but with extra information. + + +DOCX output +-------------- + +The :title:`docxwrite` device creates a DOCX file suitable for use with applications such as Word or LibreOffice, containing the text in the original document. + +Rotated text is placed into textboxes. Heuristics are used to group glyphs into words, lines and paragraphs; for some types of formatting, these heuristics may not be able to recover all of the original document structure. + +This device currently has no special configuration parameters. + + +XPS file output +---------------------------- + +The :title:`xpswrite` device writes its output according to the Microsoft XML Paper Specification. This specification was later amended to the Open XML Paper specification, submitted to ECMA International and adopted as ECMA-388. + +This device currently has no special configuration parameters. + + +The family of PDF and PostScript output devices +--------------------------------------------------- + + + +Common controls and features +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PDF and PostScript (including Encapsulated PostScript, or EPS) devices have much of their code in common, and so many of the controlling parameters are also common amongst the devices. The pdfwrite, ps2write and eps2write devices create PDF or PostScript files whose visual appearance should match, as closely as possible, the appearance of the original input (PS, PDF, XPS, PCL, PXL). There are a number of caveats as mentioned in the overview above. In addition to the general comments there are some additional points that bear mentioning. + +PCL has a graphics model which differs significantly from the PostScript or PDF one, in particular it has a form of transparency called ``RasterOps``, some aspects of which cannot be represented in PDF at a high level (or at all, in PostScript). The :title:`pdfwrite` device makes no attempt to handle this, and the resulting PDF file will not match the original input. The only way to deal with these types of file is to render the whole page to a bitmap and then 'wrap' the bitmap as a PDF file. Currently we do not do this either, but it is possible that a future enhancement may do so. + +If the input contains PDF-compatible transparency, but the :title:`ps2write` device is selected, or the :title:`pdfwrite` device is selected, but has been told to limit the PDF feature set to a version less than 1.4, the transparency cannot be preserved. In this case the entire page is rendered to a bitmap and that bitmap is 'wrapped up' in appropriate PDF or PostScript content. The output should be visually the same as the input, but since it has been rendered it will not scale up or down well, unlike the original, vector, content of the input. + +The options in the command line may include any switches that may be used with the language interpreter appropriate for the input (see :ref:`here<Use_Command line options>` for a complete list). In addition the following options are common to all the :title:`pdfwrite` family of devices, and should work when specified on the command line with any of the language interpreters. + +``-rresolution`` + Sets the resolution for pattern fills, for fonts that must be converted to bitmaps and any other rendering required (eg rendering transparent pages for output to PDF versions < 14). The default internal resolution for :title:`pdfwrite` is 720dpi. + +``-dUNROLLFORMS`` + When converting from PostScript, :title:`pdfwrite` (and :title:`ps2write`) preserve the use of Form resources as Form XObjects in the output. Some badly written PostScript can cause this to produce incorrect output (the Quality Logic CET tests for example). By setting this flag, forms will be unrolled and stored in the output each time they are used, which avoids the problems. Note that the output file will of course be larger this way. We do not attempt to preserve Form XObjects from PDF files, unless they are associated with transparency groups. + +``-dNoOutputFonts`` + Ordinarily the :title:`pdfwrite` device family goes to considerable lengths to preserve fonts from the input as fonts in the output. However in some highly specific cases it can be useful to have the text emitted as linework/bitmaps instead. Setting this switch will prevent these devices from emitting any fonts, all text will be stored as vectors (or bitmaps in the case of bitmapped fonts) in the page content stream. Note that this will produce larger output which will process more slowly, render differently and particularly at lower resolution produce less consistent text rendering. Use with caution. + +``-dCompressFonts=boolean`` + Defines whether :title:`pdfwrite` will compress embedded fonts in the output. The default value is true; the false setting is intended only for debugging as it will result in larger output. + +``-dCompressStreams=boolean`` + Defines whether :title:`pdfwrite` will compress streams other than those in fonts or pages in the output. The default value is true; the false setting is intended only for debugging as it will result in larger output. + + + + +Distiller Parameters +"""""""""""""""""""""" + +Options may also include ``-dparameter=value`` or ``-sparameter=string`` switches for setting "distiller parameters", Adobe's documented parameters for controlling the conversion of PostScript into PDF. The PostScript ``setdistillerparams`` and ``currentdistillerparams`` operators are also recognized when the input is PostScript, and provide an equivalent way to set these parameters from within a PostScript input file. + +Although the name implies that these parameters are for controlling PDF output, in fact the whole family of devices use these same parameters to control the conversion into PostScript and EPS as well. + +The :title:`pdfwrite` family of devices recognize all of the Acrobat Distiller 5 parameters defined in the DistillerParameters (version 5) document available from the Adobe web site. Cells in the table below containing '=' mean that the value of the parameter is the same as in the "default" column. + + + + +.. list-table:: + :header-rows: 1 + + * - Parameter name + - Notes + - default + - screen + - ebook + - printer + - prepress + * - AlwaysEmbed + - :ref:`(13)<DistillerParameters_note_13>` + - [ ] + - = + - = + - = + - = + * - AntiAliasColorImages + - :ref:`(0)<DistillerParameters_note_0>` + - false + - = + - = + - = + - = + * - AntiAliasGrayImages + - :ref:`(0)<DistillerParameters_note_0>` + - false + - = + - = + - = + - = + * - AntiAliasMonoImages + - :ref:`(0)<DistillerParameters_note_0>` + - false + - = + - = + - = + - = + * - ASCII85EncodePages + - + - false + - = + - = + - = + - = + * - AutoFilterColorImages + - :ref:`(1)<DistillerParameters_note_1>` + - true + - = + - = + - = + - = + * - AutoFilterGrayImages + - :ref:`(1)<DistillerParameters_note_1>` + - true + - = + - = + - = + - = + * - AutoPositionEPSFiles + - :ref:`(0)<DistillerParameters_note_0>` + - true + - = + - = + - = + - = + * - AutoRotatePages + - + - /PageByPage + - /PageByPage + - /All + - /None + - /None + * - Binding + - :ref:`(0)<DistillerParameters_note_0>` + - /Left + - = + - = + - = + - = + * - CalCMYKProfile + - :ref:`(0)<DistillerParameters_note_0>` + - () + - = + - = + - = + - = + * - CalGrayProfile + - :ref:`(0)<DistillerParameters_note_0>` + - () + - = + - = + - = + - = + * - CalRGBProfile + - :ref:`(0)<DistillerParameters_note_0>` + - () + - = + - = + - = + - = + * - CannotEmbedFontPolicy + - :ref:`(0)<DistillerParameters_note_0>` + - /Warning + - /Warning + - /Warning + - /Warning + - /Error + * - ColorACSImageDict + - :ref:`(13)<DistillerParameters_note_13>` + - :ref:`(7)<DistillerParameters_note_7>` + - :ref:`(10)<DistillerParameters_note_10>` + - :ref:`(10)<DistillerParameters_note_10>` + - :ref:`(8)<DistillerParameters_note_8>` + - :ref:`(9)<DistillerParameters_note_9>` + * - ColorConversionStrategy + - :ref:`(6)<DistillerParameters_note_6>` + - LeaveColorUnchanged + - RGB + - RGB + - UseDeviceIndependentColor + - LeaveColorUnchanged + * - ColorImageDepth + - + - -1 + - = + - = + - = + - = + * - ColorImageDict + - :ref:`(13)<DistillerParameters_note_13>` + - :ref:`(7)<DistillerParameters_note_7>` + - = + - = + - = + - = + * - ColorImageFilter + - + - /DCTEncode + - = + - = + - = + - = + * - ColorImageDownsampleThreshold + - + - 1.5 + - = + - = + - = + - = + * - ColorImageDownsampleType + - :ref:`(3)<DistillerParameters_note_3>` + - /Subsample + - /Average + - /Average + - /Average + - /Bicubic + * - ColorImageResolution + - + - 72 + - 72 + - 150 + - 300 + - 300 + * - CompatibilityLevel + - + - 1.7 + - 1.5 + - 1.5 + - 1.7 + - 1.7 + * - CompressPages + - :ref:`(14)<DistillerParameters_note_14>` + - true + - = + - = + - = + - = + * - ConvertCMYKImagesToRGB + - + - false + - = + - = + - = + - = + * - ConvertImagesToIndexed + - :ref:`(0)<DistillerParameters_note_0>` + - false + - = + - = + - = + - = + * - CoreDistVersion + - + - 4000 + - = + - = + - = + - = + * - CreateJobTicket + - :ref:`(0)<DistillerParameters_note_0>` + - false + - false + - false + - true + - true + * - DefaultRenderingIntent + - + - /Default + - = + - = + - = + - = + * - DetectBlends + - :ref:`(0)<DistillerParameters_note_0>` + - true + - = + - = + - = + - = + * - DoThumbnails + - :ref:`(0)<DistillerParameters_note_0>` + - false + - false + - false + - false + - true + * - DownsampleColorImages + - + - false + - true + - true + - false + - false + * - DownsampleGrayImages + - + - false + - true + - true + - false + - false + * - DownsampleMonoImages + - + - false + - true + - true + - false + - false + * - EmbedAllFonts + - + - true + - false + - true + - true + - true + * - EmitDSCWarnings + - :ref:`(0)<DistillerParameters_note_0>` + - false + - = + - = + - = + - = + * - EncodeColorImages + - + - true + - = + - = + - = + - = + * - EncodeGrayImages + - + - true + - = + - = + - = + - = + * - EncodeMonoImages + - + - true + - = + - = + - = + - = + * - EndPage + - :ref:`(0)<DistillerParameters_note_0>` + - -1 + - = + - = + - = + - = + * - GrayACSImageDict + - :ref:`(13)<DistillerParameters_note_13>` + - :ref:`(7)<DistillerParameters_note_7>` + - :ref:`(7)<DistillerParameters_note_7>` + - :ref:`(10)<DistillerParameters_note_10>` + - :ref:`(8)<DistillerParameters_note_8>` + - :ref:`(9)<DistillerParameters_note_9>` + * - GrayImageDepth + - + - -1 + - = + - = + - = + - = + * - GrayImageDict + - :ref:`(13)<DistillerParameters_note_13>` + - :ref:`(7)<DistillerParameters_note_7>` + - = + - = + - = + - = + * - GrayImageDownsampleThreshold + - + - 1.5 + - = + - = + - = + - = + * - GrayImageDownsampleType + - :ref:`(3)<DistillerParameters_note_3>` + - /Subsample + - /Average + - /Bicubic + - /Bicubic + - /Bicubic + * - GrayImageFilter + - + - /DCTEncode + - = + - = + - = + - = + * - GrayImageResolution + - + - 72 + - 72 + - 150 + - 300 + - 300 + * - ImageMemory + - :ref:`(0)<DistillerParameters_note_0>` + - 524288 + - = + - = + - = + - = + * - LockDistillerParams + - + - false + - = + - = + - = + - = + * - LZWEncodePages + - :ref:`(2)<DistillerParameters_note_2>` + - false + - = + - = + - = + - = + * - MaxSubsetPct + - + - 100 + - = + - = + - = + - = + * - MonoImageDepth + - + - -1 + - = + - = + - = + - = + * - MonoImageDict + - :ref:`(13)<DistillerParameters_note_13>` + - <<K -1>> + - = + - = + - = + - = + * - MonoImageDownsampleThreshold + - + - 1.5 + - = + - = + - = + - = + * - MonoImageDownsampleType + - + - /Subsample + - /Subsample + - /Subsample + - /Subsample + - /Subsample + * - MonoImageFilter + - + - /CCITTFaxEncode + - = + - = + - = + - = + * - MonoImageResolution + - + - 300 + - 300 + - 300 + - 1200 + - 1200 + * - NeverEmbed + - :ref:`(13)<DistillerParameters_note_13>` + - :ref:`(11)<DistillerParameters_note_11>` :ref:`(12)<DistillerParameters_note_12>` + - :ref:`(11)<DistillerParameters_note_11>` :ref:`(12)<DistillerParameters_note_12>` + - :ref:`(11)<DistillerParameters_note_11>` :ref:`(12)<DistillerParameters_note_12>` + - [] :ref:`(12)<DistillerParameters_note_12>` + - [] :ref:`(12)<DistillerParameters_note_12>` + * - OffOptimizations + - + - 0 + - = + - = + - = + - = + * - OPM + - + - 1 + - = + - = + - = + - = + * - Optimize + - :ref:`(0)<DistillerParameters_note_0>` :ref:`(5)<DistillerParameters_note_5>` + - false + - true + - true + - true + - true + * - ParseDSCComments + - + - true + - = + - = + - = + - = + * - ParseDSCCommentsForDocInfo + - + - true + - = + - = + - = + - = + * - PreserveCopyPage + - :ref:`(0)<DistillerParameters_note_0>` + - true + - = + - = + - = + - = + * - PreserveEPSInfo + - :ref:`(0)<DistillerParameters_note_0>` + - true + - = + - = + - = + - = + * - PreserveHalftoneInfo + - + - false + - = + - = + - = + - = + * - PreserveOPIComments + - :ref:`(0)<DistillerParameters_note_0>` + - false + - false + - false + - true + - true + * - PreserveOverprintSettings + - + - false + - false + - false + - true + - true + * - sRGBProfile + - :ref:`(0)<DistillerParameters_note_0>` + - () + - = + - = + - = + - = + * - StartPage + - :ref:`(0)<DistillerParameters_note_0>` + - 1 + - = + - = + - = + - = + * - SubsetFonts + - + - true + - = + - = + - = + - = + * - TransferFunctionInfo + - :ref:`(4)<DistillerParameters_note_4>` + - /Preserve + - = + - = + - = + - = + * - UCRandBGInfo + - + - /Remove + - /Remove + - /Remove + - /Preserve + - /Preserve + * - UseFlateCompression + - :ref:`(2)<DistillerParameters_note_2>` + - true + - = + - = + - = + - = + * - UsePrologue + - :ref:`(0)<DistillerParameters_note_0>` + - false + - = + - = + - = + - = + * - PassThroughJPEGImages + - :ref:`(15)<DistillerParameters_note_15>` + - true + - = + - = + - = + - = + * - PassThroughJPXImages + - :ref:`(16)<DistillerParameters_note_16>` + - true + - = + - = + - = + - = + +.. _DistillerParameters_note_0: + +Note 0 +^^^^^^^^^ + This parameter can be set and queried, but currently has no effect. + +.. _DistillerParameters_note_1: + +Note 1 +^^^^^^^^^ + ``-dAutoFilterxxxImages=false`` works since Ghostscript version 7.30. Older versions of Ghostscript don't examine the image to decide between JPEG and LZW or Flate compression: they always use Flate compression. + +.. _DistillerParameters_note_2: + +Note 2 +^^^^^^^^^ + Because the LZW compression scheme was covered by patents at the time this device was created, :title:`pdfwrite` does not actually use LZW compression: all requests for LZW compression are ignored. ``UseFlateCompression`` is treated as always on, but the switch ``CompressPages`` can be set to false to turn off page level stream compression. Now that the patent has expired, we could change this should it become worthwhile. + +.. _DistillerParameters_note_3: + +Note 3 +^^^^^^^^^ + The ``xxxDownsampleType`` parameters can also have the value ``/Bicubic`` (a Distiller 4 feature), this will use a Mitchell filter. (older versions of :title:`pdfwrite` simply used Average instead). If a non-integer downsample factor is used the code will clamp to the nearest integer (if the difference is less than 0.1) or will silently switch to the old bicubic filter, NOT the Mitchell filter. + +.. _DistillerParameters_note_4: + +Note 4 +^^^^^^^^^ + The default for transfer functions is to preserve them, this is because transfer functions are a device-dependent feature, a set of transfer functions designed for an RGB device will give incorrect output on a CMYK device for instance. The :title:`pdfwrite` device does now support ``/Preserve``, ``/Apply`` and ``/Remove`` (the previous documentation was incorrect, application of transfer functions was not supported). PDF 2.0 deprecates the use of transfer functions, and so when producing PDF 2.0 compatible output if the ``TransferFunctionInfor`` is set to ``/Preserve`` it will be silently replaced with ``/Apply``. You can instead specifically set ``TransferFunctionInfo`` to ``/Remove`` when producing PDF 2.0 in order to avoid the transfer function being applied. + +.. _DistillerParameters_note_5: + +Note 5 +^^^^^^^^^ + Use the ``-dFastWebView`` command line switch to 'optimize' output. + +.. _DistillerParameters_note_6: + +Note 6 +^^^^^^^^^ + The value ``UseDeviceIndependentColorForImages`` works the same as ``UseDeviceIndependentColor``. The value sRGB actually converts to RGB with the default Ghostscript conversion. The new Ghostscript-specific value Gray converts all colors to ``DeviceGray``. With the introduction of new color conversion code in version 9.11 it is no longer necessary to set ``ProcessColorModel`` when selecting Gray, RGB or CMYK. It is also no longer necessary to set ``UseCIEColor`` for ``UseDeviceIndependentColor`` to work properly, and the use of ``UseCIEColor`` is now strongly discouraged. + +.. _DistillerParameters_note_7: + +Note 7 +^^^^^^^^^ +The default image parameter dictionary is: + +.. code-block:: bash + + << /QFactor 0.9 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> + +.. _DistillerParameters_note_8: + +Note 8 +^^^^^^^^^ +The printer ACS image parameter dictionary is: + + .. code-block:: bash + + << /QFactor 0.4 /Blend 1 /ColorTransform 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> + +.. _DistillerParameters_note_9: + +Note 9 +^^^^^^^^^ +The prepress ACS image parameter dictionary is: + + .. code-block:: bash + + << /QFactor 0.15 /Blend 1 /ColorTransform 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> + +.. _DistillerParameters_note_10: + +Note 10 +^^^^^^^^^ + The screen and ebook ACS image parameter dictionary is: + + .. code-block:: bash + + << /QFactor 0.76 /Blend 1 /ColorTransform 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> + +.. _DistillerParameters_note_11: + +Note 11 +^^^^^^^^^ + The default, screen, and ebook settings never embed the 14 standard fonts (Courier, Helvetica, and Times families, Symbol, and ZapfDingbats). This behaviour is intentional but can be overridden by: + + .. code-block:: bash + + << /NeverEmbed [ ] >> setdistillerparams + +.. _DistillerParameters_note_12: + +Note 12 +^^^^^^^^^ + ``NeverEmbed`` can include CID font names. If a CID font is substituted in ``lib/cidfmap``, the substitute font name is used when the CID font is embedded, and the original CID font name is used when it is not embedded. ``NeverEmbed`` should always specify the original CID font name. + +.. _DistillerParameters_note_13: + +Note 13 +^^^^^^^^^ + The arrays ``AlwaysEmbed`` and ``NeverEmbed`` and image parameter dictionaries ``ColorACSImageDict``, ``ColorACSImageDict``, ``ColorImageDict``, ``GrayACSImageDict``, ``GrayImageDict``, ``MonoImageDict`` cannot be specified on the command line. To specify these, you must use PostScript, either by including it in the PostScript source or by passing the ``-c`` command-line parameter to Ghostscript as described in Limitations_ below. For example, including the PostScript string in your file ``in.ps``: + + .. code-block:: bash + + <</AlwaysEmbed [/Helvetica /Times-Roman]>> setdistillerparams + + is equivalent to invoking: + + .. code-block:: bash + + gs -dBATCH -dSAFER -DNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=out.pdf -c '<</AlwaysEmbed [/Helvetica /Times-Roman]>> setdistillerparams' -f in.ps + + or using the extra parameters in a file: + + .. code-block:: bash + + @params.in + + where the file ``params.in`` contains: + + .. code-block:: bash + + -c '<</AlwaysEmbed [/Helvetica /Times-Roman]>> setdistillerparams' -f in.ps + + +.. _DistillerParameters_note_14: + +Note 14 +^^^^^^^^^ + The default value of ``CompressPages`` is false for :title:`ps2write` and :title:`eps2write`. + +.. _DistillerParameters_note_15: + +Note 15 +^^^^^^^^^ + When true image data in the source which is encoded using the DCT (JPEG) filter will not be decompressed and then recompressed on output. This prevents the multiplication of JPEG artefacts caused by lossy compression. ``PassThroughJPEGImages`` currently only affects simple JPEG images. It has no effect on JPX (JPEG2000) encoded images (see below) or masked images. In addition this parameter will be ignored if the :title:`pdfwrite` device needs to modify the source data. This can happen if the image is being downsampled, changing colour space or having transfer functions applied. Note that this parameter essentially overrides the ``EncodeColorImages`` and ``EncodeGrayImages`` parameters if they are false, the image will still be written with a ``DCTDecode`` filter. NB this feature currently only works with PostScript or PDF input, it does not work with PCL, PXL or XPS input. + +.. _DistillerParameters_note_16: + +Note 16 +^^^^^^^^^ + When true image data in the source which is encoded using the JPX (JPEG 2000) filter will not be decompressed and then recompressed on output. This prevents the multiplication of JPEG artefacts caused by lossy compression. ``PassThroughJPXImages`` currently only affects simple JPX encoded images. It has no effect on JPEG encoded images (see above) or masked images. In addition this parameter will be ignored if the :title:`pdfwrite` device needs to modify the source data. This can happen if the image is being downsampled, changing colour space or having transfer functions applied. Note that this parameter essentially overrides the ``EncodeColorImages`` and ``EncodeGrayImages`` parameters if they are false, the image will still be written with a ``JPXDecode`` filter. NB this feature currently only works with PostScript or PDF input, it does not work with PCL, PXL or XPS input. + + + +Color Conversion and Management +"""""""""""""""""""""""""""""""""""""""""""" + +As of the 9.11 pre-release, the color management in the :title:`pdfwrite` family has been substantially altered so that it now uses the same Color Management System as rendering (the default is LCMS2). This considerably improves the color handling in both :title:`pdfwrite` and :title:`ps2write`, particularly in the areas of ``Separation`` and :title:`devicen` color spaces, and ``Indexed`` color spaces with images. + +Note that while :title:`pdfwrite` uses the same CMS as the rendering devices, this does not mean that the entire suite of options is available, as described in the ``GS9_Colour Management.pdf`` file. The colour management code has no effect at all unless either ``ColorConversionStrategy`` or ``ConvertCMYKImagesToRGB`` is set, or content has to be rendered to an image (this is rare and usually required only when converting a PDF file with transparency to a version < PDF 1.4). + +Options based on object type (image, text, linework) are not used, all objects are converted using the same scheme. ``-dKPreserve`` has no effect because we will not convert CMYK to CMYK. ``-dDeviceGrayToK`` also has no effect; when converting to CMYK ``DeviceGray`` objects are left in ``DeviceGray`` since that can be mapped directly to the K channel. + +The ``ColorConversionStrategy`` switch can now be set to ``LeaveColorUnchanged``, ``Gray``, ``RGB``, ``CMYK`` or ``UseDeviceIndependentColor``. Note that, particularly for :title:`ps2write`, ``LeaveColorUnchanged`` may still need to convert colors into a different space (ICCbased colors cannot be represented in PostScript for example). ``ColorConversionStrategy`` can be specified either as; a string by using the ``-s`` switch (``-sColorConversionStrategy=RGB``) or as a name using the ``-d`` switch (``-dColorConversionStrategy=/RGB``). +:title:`ps2write` cannot currently convert into device-independent color spaces, and so ``UseDeviceIndependentColor`` should not be used with :title:`ps2write` (or :title:`eps2write`). + +All other color spaces are converted appropriately. ``Separation`` and :title:`devicen` spaces will be preserved if possible (:title:`ps2write` cannot preserve :title:`devicen` or ``Lab``) and if the alternate space is not appropriate a new alternate space will be created, e.g. a ``[/Separation (MyColor) /DeviceRGB {...}]`` when the ``ColorConversionStrategy`` is set to CMYK would be converted to ``[/Separation (MyColor) /DeviceCMYK {...}]`` The new tint transform will be created by sampling the original tint transform, converting the RGB values into CMYK, and then creating a function to linearly interpolate between those values. + +The ``PreserveSeparation`` switch now controls whether the :title:`pdfwrite` family of devices will attempt to preserve ``Separation`` spaces. If this is set to false then all ``Separation`` colours will be converted into the current device space specified by ``ProcessColorModel``. + + + +Setting page orientation +"""""""""""""""""""""""""""""""""""""""""""" + +By default Ghostscript determines viewing page orientation based on the dominant text orientation on the page. Sometimes, when the page has text in several orientations or has no text at all, wrong orientation can be selected. + +Acrobat Distiller parameter ``AutoRotatePages`` controls the automatic orientation selection algorithm. On Ghostscript, besides input stream, Distiller parameters can be given as command line arguments. For instance: ``-dAutoRotatePages=/None`` or ``/All`` or ``/PageByPage``. + +When there is no text on the page or automatic page rotation is set to ``/None`` an orientation value from ``setpagedevice`` is used. Valid values are: 0 (portrait), 3 (landscape), 2 (upside down), and 1 (seascape). The orientation can be set from the command line as ``-c "<</Orientation 3>> setpagedevice"`` using Ghostscript directly but cannot be set in ``ps2pdf``. See Limitations_ below. + +Ghostscript passes the orientation values from DSC comments to the :title:`pdfwrite` driver, and these are compared with the auto-rotate heuristic. If they are different then the DSC value will be used preferentially. If the heuristic is to be preferred over the DSC comments then comment parsing can be disabled by setting ``-dParseDSCComments=false``. + + +Controls and features specific to PostScript and PDF input +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``-dPDFSETTINGS=configuration`` + Presets the "distiller parameters" to one of the following predefined settings: + +- ``/screen`` selects low-resolution output similar to the Acrobat Distiller (up to version X) "Screen Optimized" setting. + +- ``/ebook`` selects medium-resolution output similar to the Acrobat Distiller (up to version X) "eBook" setting. + +- ``/printer`` selects output similar to the Acrobat Distiller "Print Optimized" (up to version X) setting. + +- ``/prepress`` selects output similar to Acrobat Distiller "Prepress Optimized" (up to version X) setting. + +- ``/default`` selects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file. + + +.. note :: + + Adobe has recently changed the names of the presets it uses in Adobe Acrobat Distiller, in order to avoid confusion with earlier versions we do not plan to change the names of the ``PDFSETTINGS`` parameters. The precise value for each control is listed in the table above. + +Please be aware that the ``/prepress`` setting does not indicate the highest quality conversion. Using any of these presets will involve altering the input, and as such may result in a PDF of poorer quality (compared to the input) than simply using the defaults. The 'best' quality (where best means closest to the original input) is obtained by not setting this parameter at all (or by using /default). + +The ``PDFSETTINGS`` presets should only be used if you are sure you understand that the output will be altered in a variety of ways from the input. It is usually better to adjust the controls individually (see the table below) if you have a genuine requirement to produce, for example, a PDF file where the images are reduced in resolution. + + + +Controls and features specific to PCL and PXL input +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Many of the controls used for distiller parameters can be used on the command line with the ``-d`` or ``-s`` switches, and these will work correctly with PCL or PXL input. However, some controls (e.g. ``/NeverEmbed``) do not take simple numeric or string arguments, and these cannot be set from the command line. When the input is PostScript or PDF we can use the ``-c`` and ``-f`` switches to send PostScript through the interpreter to control these parameters, but clearly this is not possible when the interpreter does not understand PostScript. In addition some features are controlled using the PostScript ``pdfmark`` operator and again that clearly is not possible unless we are using a PostScript interpreter to read the input. + +To overcome this new, GhostPCL-specific, PJL parameters have been added. These parameters are defined as ``PDFMARK`` and ``SETDISTILLERPARAMS``. In order to reduce confusion when using PostScript and PCL as inputs these PJL parameters take essentially the same PostScript constructs as the corresponding PostScript operators ``pdfmark`` and ``setdistillerparams``. However it is important to realise that these are not processed by a full PostScript interpreter, and there are syntactic rules which must be followed carefully when using these parameters. + +You cannot use arbitrary PostScript operators, only boolean, number, name, string, array and dictionary objects are supported (but see ``PUTFILE`` later). All tokens must be separated by white space, so while this ``[/Test(string)]`` is perfectly valid in PostScript, you must instead write it as ``[ /Test (string) ]`` for PJL parsing. All ``PDFMARK`` and ``SETDISTILLERPARAMS`` must be set as ``DEFAULT``, the values must be on a single line, and delimited by ``""``. + +``pdfmarks`` sometimes require the insertion of file objects (especially for production of PDF/A files) so we must find some way to handle these. This is done (for the ``pdfmark`` case only) by defining a special (non-standard) pdfmark name ``PUTFILE``, this simply takes the preceding string, and uses it as a fully qualified path to a file. Any further ``pdfmark`` operations can then use the named object holding the file to access it. + +The easiest way to use these parameters is to create a 'settings' file, put all the commands in it, and then put it on the command line immediately before the real input file. For example: + +.. code-block:: bash + + ./gpcl6 -sDEVICE=pdfwrite -dPDFA=1 -dCompressPages=false -dCompressFonts=false -sOutputFile=./out.pdf ./pdfa.pjl ./input.pcl + +Where ``pdfa.pjl`` contains the PJL commands to create a PDF/A-1b file (see example below). + +Example creation of a PDF/A output file +"""""""""""""""""""""""""""""""""""""""""""""" + +For readability the line has been bisected, when used for real this must be a single line. The 'ESC' represents a single byte, value ``0x1B``, an escape character in ASCII. The line must end with an ASCII newline ``(\n, 0x0A)`` and this must be the only newline following the ``@PJL``. The line breaks between ``""`` below should be replaced with space characters, the double quote characters (``"``) are required. + +.. code-block:: postscript + + ESC%-12345X + @PJL DEFAULT PDFMARK = " + [ /_objdef {icc_PDFA} /type /stream /OBJ pdfmark + [ {icc_PDFA} << /N 3 >> /PUT pdfmark + [ {icc_PDFA} (/ghostpdl/iccprofiles/default_rgb.icc) /PUTFILE pdfmark + [ /_objdef {OutputIntent_PDFA} /type /dict /OBJ pdfmark + [ {OutputIntent_PDFA} << /S /GTS_PDFA1 /Type /OutputIntent /DestOutputProfile {icc_PDFA} /OutputConditionIdentifier (sRGB) >> /PUT pdfmark + [ {Catalog} << /OutputIntents [{OutputIntent_PDFA}] >> /PUT pdfmark + [ /Author (Ken) /Creator (also Ken) /Title (PDF/A-1b) /DOCINFO pdfmark + " + + +Example using DISTILLERPARAMS to set the quality of JPEG compression +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. code-block:: postscript + + ESC%-12345X @PJL DEFAULT SETDISTILLERPARAMS = "<< /ColorImageDict << /QFactor 0.7 /Blend 1 /HSamples [ 2 1 1 2 ] /VSamples [ 2 1 1 2 ] >> >>" + + + + +PDF file output +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``-dMaxInlineImageSize=integer`` + Specifies the maximum size of an inline image, in bytes. For images larger than this size, :title:`pdfwrite` will create an XObject instead of embedding the image into the context stream. The default value is 4000. Note that redundant inline images must be embedded each time they occur in the document, while multiple references can be made to a single XObject image. Therefore it may be advantageous to set a small or zero value if the source document is expected to contain multiple identical images, reducing the size of the generated PDF. + +``-dDoNumCopies`` + When present, causes :title:`pdfwrite` to use the ``#copies`` or ``/NumCopies`` entry in the page device dictionary to duplicate each page in the output PDF file as many times as the 'copies' value. This is intended for use by workflow applications like :title:`cups` and should not be used for generating general purpose PDF files. In particular any ``pdfmark`` operations which rely on page numbers, such as ``Link`` or ``Outline`` annotations will not work correctly with this flag. + +``-dDetectDuplicateImages`` + Takes a Boolean argument, when set to true (the default) :title:`pdfwrite` will compare all new images with all the images encountered to date (NOT small images which are stored in-line) to see if the new image is a duplicate of an earlier one. If it is a duplicate then instead of writing a new image into the PDF file, the PDF will reuse the reference to the earlier image. This can considerably reduce the size of the output PDF file, but increases the time taken to process the file. This time grows exponentially as more images are added, and on large input files with numerous images can be prohibitively slow. Setting this to false will improve performance at the cost of final file size. + +``-dFastWebView`` + Takes a Boolean argument, default is false. When set to true :title:`pdfwrite` will reorder the output PDF file to conform to the Adobe 'linearised' PDF specification. The Acrobat user interface refers to this as 'Optimised for Fast Web Viewing'. Note that this will cause the conversion to PDF to be slightly slower and will usually result in a slightly larger PDF file. + This option is incompatible with producing an encrypted (password protected) PDF file. + +``-dPreserveAnnots=boolean`` + We now attempt to preserve most annotations from input PDF files as annotations in the output PDF file (note, not in output PostScript!). There are a few annotation types which are not preserved, most notably ``Link`` and ``Widget`` annotations. However, should you wish to revert to the old behaviour, or find that the new behaviour leads to problems, you can set this switch to false which will cause all annotations to be inserted into the page content stream, instead of preserved as annotations. + + In addition, finer control is available by defining an array ``/PreserveAnnotTypes``. Annotation types listed in this array will be preserved, whilst those not listed will be drawn according to the setting of ``ShowAnnots`` and ``ShowAnnotTypes``. By using the controls ``PreserveAnnots``, ``PreserveAnnotTypes``, ``ShowAnnots`` and ``ShowAnnotTypes`` it is possible to select by annotation type whether annotations are preserved as annotations, drawn into the page, or simply dropped. + + To use this feature: ``-c "/PreserveAnnotTypes [....] def" -f <input file>`` + + Where the array can contain one or more of the following names: ``/Stamp``, ``/Squiggly``, ``/Underline``, ``/Link``, ``/Text``, ``/Highlight``, ``/Ink``, ``/FreeText``, ``/StrikeOut`` and ``/stamp_dict``. + + For example, adding the follow to the command line: ``-c "/PreserveAnnotTypes [/Text /UnderLine] def" -f <input file>`` would preserve only annotations with the subtypes "Text" and "UnderLine". + +``-dPreserveMarkedContent=boolean`` + We now attempt to preserve marked content from input PDF files through to the output PDF file (note, not in output PostScript!) This does not include marked content relating to optional content, because currently we do not preserve optional content, it is instead applied by the interpreter. + + This control also requires the PDF interpreter to pass the marked content to the :title:`pdfwrite` device, this is only done with the new (C-based) PDF interpreter. The old (PostScript-based) interpreter does not support this feature and will not pass marked content to the :title:`pdfwrite` device. + +``-dOmitInfoDateboolean`` + Under some conditions the ``CreationDate`` and ``ModDate`` in the ``/Info`` dictionary are optional and can be omitted. They are required when producing PDF/X output however. This control will allow the user to omit the ``/CreationDate`` and ``/ModDate`` entries in the ``Info`` dictionary (and the corresponding information in the XMP metadata, if present). If you try to set this control when writing PDF/X output, the device will give a warning and ignore this control. + +``-dOmitIDboolean`` + Under some conditions the ``/ID`` array trailer dictionary is optional and can be omitted. It is required when producing PDF 2.0, or encrypted PDFs however. This control will allow the user to omit the ``/ID`` entry in the trailer dictionary. If you try to set this control when writing PDF 2.0 or encrypted PDF output, the device will give a warning and ignore this control. + +``-dOmitXMPboolean`` + Under some conditions the XMP ``/Metadata`` entry in the ``Catalog`` dictionary is optional and can be omitted. It is required when producing PDF/A output however. This control will allow the user to omit the ``/Metadata`` entry in the ``Catalog`` dictionary. If you try to set this control when writing PDF/A output, the device will give a warning and ignore this control. + + + +The following options are useful for creating PDF 1.2 files: + +``-dPatternImagemask=boolean`` + With CompatibilityLevel < 1.3 it specifies whether the target viewer handles ``ImageMask`` with a pattern color. Some old viewers, such as Ghostscript 3.30 fail with such constructs. Setting this option to false, one can get more compatibility, but the mask interpolation is lost. With CompatibilityLevel ≥ 1.3 this option is ignored. Default value is false. + +``-dMaxClipPathSize=integer`` + Specifies the maximum number of elements in the clipping path that the target viewer can handle. This option is used only with ``CompatibilityLevel < 1.3`` and ``PatternImagemask=false``, and only when converting a mask into a clipping path. If the clipping path exceeds the specified size, the masked image and the clipping path is decomposed into smaller images. The value of the option counts straight path segments (curved segments are not used for representing a mask). Default value is 12000. + +``-dMaxShadingBitmapSize=integer`` + Specifies the maximum number of bytes allowed for representing a shading as a bitmap. If a shading exceeds this value, the resolution of the output bitmap is reduced to fit into the specified number of bytes. Note that the number of bytes depends on the number of color components in ``ProcessColorModel`` or ``ColorConversionStrategy``, assumes 8 bits per sample, and doesn't consider image compression or downsampling. The image is rendered at the current resolution as specified by ``-r`` or the default of 720 dpi. Default value is 256000. In general larger values will result in higher quality, but the output file size may increase dramatically, particularly with shadings which cover large areas. Shadings should generally only be rendered to images if ``CompatibilityLevel`` is 1.2 or less or if ``ColorCoversionStrategy`` specifies a color space different to that of the shading. + +``-dHaveTrueTypes=boolean`` + With ``CompatibilityLevel < 1.3`` it specifies whether the target viewer can handle TrueType fonts. If not, TrueType fonts are converted into raster fonts with resolution specified in ``HWResolution``. Note that large text at higher resolutions results in very large bitmaps which are likely to defeat caching in many printers. As a result the text is emitted as simple images rather than as a (type 3) bitmap font. The PostScript user parameter ``MaxFontItem`` can be used to increase the maximum size of a cache entry which will increase the size/resolution of the text which can be stored in a font. With ``CompatibilityLevel ≥ 1.3`` this option is ignored. Default value is true. + +The following options are useful for creating PDF 1.3 files: + +``-dHaveTransparency=boolean`` + With ``CompatibilityLevel ≥ 1.4`` it specifies whether the target viewer can handle PDF 1.4 transparency objects. If not, the page is converted into a single plain image with all transparency flattened. Default value is true. + +The following option specifies creation of a PDF/X-3 file: + +``-dPDFX=boolean`` + Specifies the generated document is to follow the PDF/X-3 standard. When true, a DefaultRGB ColorSpace resource must be defined, and options ``NOSUBSTDEVICECOLORS``, ``NOCIE`` must not be specified. Default value is false. + + The :title:`pdfwrite` device does not currently support PDF/X versions other than 3. + + +When generating a PDF/X-3 document, Ghostscript performs the following special actions to satisfy the PDF/X-3 standard: + +- All fonts are embedded. + +- ``DeviceRGB`` color space is substituted with the ``DefaultRGB`` color space, which must be defined in the ``ColorSpace`` category. The easiest way is to provide it in the ``DefaultRGB`` file in the resource directory. + +- ``DeviceRGB`` color values are passed unchanged. If a user needs a non trivial color adjustment, a non trivial ``DefaultRGB`` color space must be defined. + +- Transfer functions and halftone phases are skipped. + +- ``/PS pdfmark`` interprets the DataSource stream or file. + +- ``TrimBox`` and ``BleedBox`` entries are generated in page descriptions. Their values can be changed using the ``PDFXTrimBoxToMediaBoxOffset``, ``PDFXSetBleedBoxToMediaBox``, and ``PDFXBleedBoxToTrimBoxOffset`` distiller parameters (see below). + + +The following switches are used for creating encrypted documents: + +``-sOwnerPassword=string`` + Defines that the document be encrypted with the specified owner password. + +``-sUserPassword=string`` + Defines the user password for opening the document. If empty, the document can be opened with no password, but the owner password is required to edit it. + +``-dPermissions=number`` + Defines the PDF permissions flag field. Negative values are allowed to represent unsigned integers with the highest bit set. See the PDF Reference manual for the meaning of the flag bits. + +``-dEncryptionR=number`` + Defines the encryption method revision number - either 2 or 3. + +``-dKeyLength=number`` + Defines the length (in bits) of the encryption key. Must be a multiple of 8 in the interval [40, 128]. If the length isn't 40, ``-dEncryptionR`` must be 3. + + +The following switches are used for generating metadata according to the Adobe XMP specification : + + +``-sDocumentUUID=string`` + Defines a ``DocumentID`` to be included into the document Metadata. If not specified, Ghostscript generates an UUID automatically. Otherwise the specified string is copied into the document without checking its syntax or consistence. + + Note that Adobe XMP specification requires ``DocumentID`` must be same for all versions of a document. Since Ghostscript does not provide a maintenance of document versions, users are responsible to provide a correct UUID through this parameter. + + Note that Ghostscript has no access to the host node ID due to a minimization of platform dependent modules. Therefore it uses an MD5 hash of the document contents for generating UUIDs. + +``-sInstanceUUID=string`` + Defines a instance ID to be included into the document ``Metadata``. If not specified, Ghostscript generates an UUID automatically. Otherwise the specified string is copied into the document without checking its syntax or consistence. + + Note that the Adobe XMP specification requires the instance ID to be unique for all versions of the document. This parameter may be used to disable unique ID generation for debug purposes. + + When none of ``DocumentUUID`` and ``InstanceUUID`` are specified, the generated ``DocumentID`` appears same as instance ID. + +``-sDocumentTimeSeq=integer`` + Defines an integer to be used as a deconflictor for generating UUIDs, when several invocations of Ghostscript create several PDF documents within same clock quantum (tick). Mainly reserved for very fast computers and/or multithreading applications, which may appear in future. If both ``DocumentUUID`` and ``InstanceUUID`` are specified, ``DocumentTimeSeq`` is ignored. + + +``-sDSCEncoding=string`` + Defines the name of a Postscript encoding in which DSC comments in the source document are encoded. If specified, the comments are converted from that encoding into Unicode UTF-8 when writing ``Metadata``. If not specified, the comments are copied to ``Metadata`` with no conversion. Note that Adobe Distiller for Windows uses the default locale's code page for this translation, so it's result may differ from Ghostscript. Adobe Acrobat appears to use ``PDFDocEncoding`` when displaying document's properties, so we recommend this value. + +``-sUseOCR=string`` + Controls the use of OCR in :title:`pdfwrite`. If enabled this will use an OCR engine to analyse the glyph bitmaps used to draw text in a PDF file, and the resulting Unicode code points are then used to construct a ``ToUnicode CMap``. + + PDF files containing ``ToUnicode CMaps`` can be searched, use copy/paste and extract the text, subject to the accuracy of the ``ToUnicode CMap``. Since not all PDF files contain these it can be beneficial to create them. + + Note that, for English text, it is possible that the existing standard character encoding (which most PDF consumers will fall back to in the absence of Unicode information) is better than using OCR, as OCR is not a 100% reliable process. OCR processing is also comparatively slow. + + For the reasons above it is useful to be able to exercise some control over the action of :title:`pdfwrite` when OCR processing is available, and the UseOCR parameter provides that control. There are three possible values: + + - Never Default - don't use OCR at all even if support is built-in. + + - AsNeeded If there is no existing ToUnicode information, use OCR. + + - Always Ignore any existing information and always use OCR. + + Our experimentation with the Tesseract OCR engine has shown that the more text we can supply for the engine to look at, the better the result we get. We are, unfortunately, limited to the graphics library operations for text as follows. + + The code works on text 'fragments'; these are the text sequences sent to the text operators of the source language. Generally most input languages will try to send text in its simplest form, eg "Hello", but the requirements of justification, kerning and so on mean that sometimes each character is positioned independently on the page. + + So :title:`pdfwrite` renders all the bitmaps for every character in the text document, when set up to use OCR. Later, if any character in the font does not have a Unicode value already we use the bitmaps to assemble a 'strip' of text which we then send to the OCR engine. If the engine returns a different number of recognised characters than we expected then we ignore that result. We've found that (for English text) constructions such as ". The" tend to ignore the full stop, presumably because the OCR engine thinks that it is simply noise. In contrast "text." does identify the full stop correctly. So by ignoring the failed result we can potentially get a better result later in the document. + + Obviously this is all heuristic and undoubtedly there is more we can do to improve the functionality here, but we need concrete examples to work from. + + + +PostScript file output +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :title:`ps2write` device handles the same set of distiller parameters as are handled by the :title:`pdfwrite` device (and 2 unique extensions, see below). + +The option ``-dMaxInlineImageSize=integer`` must not be used with :title:`ps2write` as all images are inline in PostScript. + +There are also two additional (not Adobe-standard) Distiller parameters, specific to :title:`ps2write`: + +``/PSDocOptions string`` + No default value. If defined, the contents of the string will be emitted in the output PostScript prolog enclosed within ``%%BeginSetup`` and ``%%EndSetup`` comments. This is intended as a means of introducing device-specific document wide setup or configuration options into the output. Default media selection, printer resolution etc might be included here. + +``/PSPageOptions array of strings`` + No default value. If defined, the contents of the strings in the array will be emitted in the output PostScript at the start of each page, one string per page, enclosed within ``%%BeginPageSetup`` and ``%%EndPageSetup`` comments. This is intended as a means of introducing device-specific setup or configuration options into the output on a page by page basis. The strings are used from the array sequentially, if there are more pages than strings then we 'wrap round' and start again with the first string. This makes it convenient to do setup for even/odd pages by simply including 2 strings in the array. + +.. note:: + + Executing ``setpagedevice`` will reset distiller parameters to the default, if you use any of these options via ``setdistillerparams``, and expect to execute ``setpagedevice``, you should set ``/LockDistillerParams`` true. Ordinarily the PDF interpreter executes ``setpagedevice`` for every page in order to set the media size. + +.. note:: + + The strings contained in ``PSDocOptions``, and the ``PSPageOptions`` array, are written verbatim to the output. No error checking is (or can be) performed on these strings and it is the users responsibility to ensure they contain well formed PostScript which does not cause errors on the target device. + + +There are also the following ps2write specific options : + +``-dProduceDSC=boolean`` + Default value is true. When this value is true the output PostScript file will be constructed in a way which is compatible with the Adobe Document Structuring Convention, and will include a set of comments appropriate for use by document managers. This enables features such as page extraction, N-up printing and so on to be performed. When set to false, the output file will not be DSC-compliant. Older versions of Ghostscript cannot produce DSC-compliant output from ps2write, and the behaviour for these older versions matches the case when ``ProduceDSC`` is false. + +``-dCompressEntireFile=boolean`` + When this parameter is true, the ``LZWEncode`` and ``ASCII85Encode`` filters will be applied to the entire output file. In this case ``CompressPages`` should be false to prevent a dual compression. When this parameter is false, these filters will be applied to the initial procset only, if ``CompressPages`` is true. Default value is false. + +.. note:: + + It is not possible to set ``CompressEntireFile`` when ``ProduceDSC`` is true as a single compressed object cannot conform to the DSC. It is possible to set ``CompressPages`` which will also compress the ``ps2write ProcSet``. + + +Controlling device specific behaviour +"""""""""""""""""""""""""""""""""""""""""" + +A few options can be used to influence the behavior of a printer or PostScript interpreter that reads the result of ``ps2ps2``. All of these options are incompatible with DSC-compliant PostScript, in order to use any of them ``ProduceDSC`` must be set to false. + +``-dRotatePages=boolean`` + The printer will rotate pages for a better fit with the physical size. Default value : false. Must be false if ``-dSetPageSize=true``. + +``-dFitPages=boolean`` + The printer will scale pages down to better fit the physical page size. The rendering quality may be poor due to the scaling, especially for fonts which Ghostscript had converted into bitmaps (see the :title:`ps2write` device parameter ``HaveTrueTypes``; See options about the ``PageSize`` entry of the ``Policies`` dictionary while the conversion step). Default value : false. Must be false if ``-dSetPageSize=true`` or ``-dCenterPages=true``. + +``-dCenterPages=boolean`` + The printer will center the page image on the selected media. Compatible with ``-dRotatePages=true``, which may rotate the image on the media if it fits better, and then center it. Default value : false. Must be false if ``-dSetPageSize=true`` or ``-dFitPages=true``. + +``-dSetPageSize=boolean`` + The printer will try to set page size from the job. Only use with printers which can handle random ``PageSize``. Defaults to true, must be false if ``-dRotatePages=true``, ``-dCenterPages=true`` or ``-dFitPages=true``. + +``-dDoNumCopies=boolean`` + The PostScript emitted by :title:`ps2write` will try to use ``copypage`` to create the number of copies originally requested. Note that this relies on the level 2 semantics for ``copypage`` and will not reliably work on language level 3 devices (such as Ghostscript itself). Defaults to false. + + This flag is not compatible with the ``ProduceDSC`` flag which will take precedence if set. + + +These correspond to keys in the Postscript userdict of the target printer's virtual memory to control its behavior while executing a job generated with :title:`ps2write`. + +These keys can be set when executing using the :title:`ps2write` device, this 'fixes' the resulting behaviour according to which key has been set. If these keys are not defined during conversion, the resulting PostScript will not attempt any form of media selection. In this case the behaviour can then be modified by setting the keys, either by modifying the resulting PostScript or setting the values in some other manner on the target device. + +See also the distiller params ``PSDocOptions`` and ``PSPageOptions`` mentioned :ref:`above<Distiller Parameters>`. + + + +Encapsulated PostScript (EPS) file output +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :title:`eps2write` device is the same as the :title:`ps2write` device, except that it produces Encapsulated PostScript, which is intended to be imported into another document and treated as a 'black box'. There are certain restrictions which EPS files must follow, the primary one being that they must be DSC conformant. This means that you must not set ``-dProduceDSC`` to false. + +In addition EPS files may only contain a single page and may not contain device-specific PostScript. You should therefore not use the ``PSDocOptions`` or ``PSPageOptions`` or any of the switches noted in the :title:`ps2write` section above under `Controlling device specific behaviour`_. + + + + +Creating a PDF/X-3 document +---------------------------------- + +To create a PDF/X-3 document from a Postscript or a PDF file, you should : + +- Specify the :title:`pdfwrite` device or use the ``ps2pdf`` script. + +- Specify the ``-dPDFX`` option. It provides the document conformity and forces ``-dCompatibilityLevel=1.3``. + +- Specify ``-sColorConversionStrategy=Gray``, ``-sColorConversionStrategy=CMYK`` or ``-sColorConversionStrategy=UseDeviceIndependentColor`` (RGB is not allowed). If you plan to create a device-independent color PDF file then you should set the ``ProcessColorModel`` using ``-sProcessColorModel=DeviceGray`` or ``-sProcessColorModel=DeviceCMYK``. + +- Specify a PDF/X definition file before running the input document. It provides additional information to be included into the output document. A sample PDF/X definition file may be found in ``gs/lib/PDFX_def.ps``. You will need to modify the content of this file; in particular you must alter the ``/ICCProfile`` so that it points to a valid ICC profile for your ``OutputCondition``. The string '(...)' defining the ICCProfile must be a fully qualified device and path specification appropriate for your Operating System. + +- If a registered printing condition is applicable, specify its identifier in the PDF/X definition file. Otherwise provide an ICC profile and specify it in the PDF/X definition file as explained below. + +- Provide a ``DefaultRGB`` resource file in the ``ColorSpace`` resource category. Either define it in the PDF/X definition file, or provide a definition of ``gs/Resource/ColorSpace/DefaultRGB``. ``gs/Resource/ColorSpace/DefaultRGB`` is usually distributed with Ghostscript, its content may not necessarily satisfy your needs, see below. + + +.. note:: + + Unless ``-dNOSAFER`` is specified (NOT reccomended!) the ICC profile will be read using the ``SAFER`` file permissions; you must ensure that the profile is in a directory which is readable according to the ``SAFER`` permissions, or that the file itself is specifically made readable. See :ref:`-dSAFER<Use Safer>` for details of how to set file permissions for ``SAFER``. + +As mentioned above, the PDF/X definition file provides special information, which the PDF/X-3 standard requires. You can find a sample file in ``gs/lib/PDFX_def.ps``, and edit it according to your needs. The file follows Postscript syntax and uses the operator ``pdfmark`` to pass the special information. To ease customisation the lines likely to need editing in the sample file are marked with the comment ``% Customize``. They are explained below. + + +``OutputCondition string`` + Defines an ``OutputCondition`` value for the output intent dictionary. + +``OutputConditionIdentifier string`` + Defines an ``OutputConditionIdentifier`` value for the output intent dictionary. + +``ICCProfile string`` + May be omitted if ``OutputConditionIdentifier`` specifies a registered identifier of characterized printing condition (see `IPA_2003-11_PDFX.pdf`_). Defines a file name of an ICC profile file to be included into the output document. You may specify either an absolute file name, or a relative path from the working directory. + +``Title string`` + Defines the document title. Only useful if the source Postscript file doesn't define a title with DSC comments. Otherwise remove entire line from definition file. + +``Info string`` + Defines an ``Info`` value for the output intent dictionary. + + + +The Ghostscript distribution does not contain an ICC profile to be used for creating a PDF/X-3 document. Users should either create an appropriate one themselves, or use one from a public domain, or create one with the PDF/X-3 inspector freeware. + +The PDF/X-3 standard requires a ``TrimBox`` entry to be written for all page descriptions. This is an array of four offsets that specify how the page is to be trimmed after it has been printed. It is set to the same as ``MediaBox`` by default unless the ``PDFXTrimBoxToMediaBoxOffset`` distiller parameter is present. It accepts offsets to the ``MediaBox`` as an array [left right top bottom], e.g., the PostScript input code ``<< /PDFXTrimBoxToMediaBoxOffset [10 20 30 40] >> setdistillerparams`` specifies that 10 points will be trimmed at the left, 20 points at the right, 30 points at the top, and 40 points at the bottom. + +Another page entry is the ``BleedBox``. It gives the area of the page to which actual output items may extend; cut marks, color bars etc. must be positioned in the area between the ``BleedBox`` and the ``MediaBox``. The ``TrimBox`` is always contained within the ``BleedBox``. By default, the ``PDFXSetBleedBoxToMediaBox`` distiller parameter is true, and the ``BleedBox`` is set to the same values as the ``MediaBox``. If it is set to false, the ``PDFXBleedBoxToTrimBoxOffset`` parameter gives offset to the ``TrimBox``. It accepts a four-value array in the same format as the ``PDFXTrimBoxToMediaBoxOffset`` parameter. + + +Here is a sample command line to invoke Ghostscript for generating a PDF/X-3 document : + + +.. code-block:: bash + + gs -dPDFX -dBATCH -dNOPAUSE -sColorConversionStrategy=CMYK -sDEVICE=pdfwrite -sOutputFile=out-x3.pdf PDFX_def.ps input.ps + + +Please also see the ``PDFACompatibilityPolicy`` control described under `Creating a PDF/A document`_. The same control is now used to specify the desired behaviour when an input file cannot be converted 'as is' into a PDF/X file. + + + +Creating a PDF/A document +------------------------------ + +To create a PDF/A document, please follow the instructions for `Creating a PDF/X-3 document`_, with the following exceptions : + +- Specify the :title:`pdfwrite` device or use the ``ps2pdf`` script. + +- Specify the ``-dPDFA`` option to specify ``PDF/A-1``, ``-dPDFA=2`` for ``PDF/A-2`` or ``-dPDFA=3`` for ``PDF/A-3``. + +- Specify ``-sColorConversionStrategy=RGB``, ``-sColorConversionStrategy=CMYK`` or ``-sColorConversionStrategy=UseDeviceIndependentColor``. If you plan to create a device-independent color PDF file then you should set the ``ProcessColorModel`` using ``-sProcessColorModel=DeviceRGB`` or ``-sProcessColorModel=DeviceCMYK``. + +- Specify a PDF/A definition file before running the input document. It provides additional information to be included in the output document. A sample PDF/A definition file may be found in ``gs/lib/PDFA_def.ps``. You will need to modify the content of this file; in particular you must alter the ``/ICCProfile`` so that it points to a valid ICC profile for your ``OutputIntent``. The string '(...)' defining the ICCProfile must be a fully qualified device and path specification appropriate for your Operating System. + + +There is one additional control for PDF/A output: + + +``PDFACompatibilityPolicy integer`` + When an operation (e.g. ``pdfmark``) is encountered which cannot be emitted in a PDF/A compliant file, this policy is consulted, there are currently three possible values: + + ``0`` - (default) Include the feature or operation in the output file, the file will not be PDF/A compliant. Because the document ``Catalog`` is emitted before this is encountered, the file will still contain PDF/A metadata but will not be compliant. A warning will be emitted in this case. + + ``1`` - The feature or operation is ignored, the resulting PDF file will be PDF/A compliant. A warning will be emitted for every elided feature. + + ``2`` - Processing of the file is aborted with an error, the exact error may vary depending on the nature of the PDF/A incompatibility. + + +Here is a sample command line to invoke Ghostscript for generating a PDF/A document: + +.. code-block:: bash + + gs -dPDFA=1 -dBATCH -dNOPAUSE -sColorConversionStrategy=RGB -sDEVICE=pdfwrite -sOutputFile=out-a.pdf PDFA_def.ps input.ps + + + +Ghostscript PDF Printer Description +----------------------------------------- + +To assist with creating a PostScript file suitable for conversion to PDF, Ghostscript includes ``ghostpdf.ppd``, a PostScript Printer Description (PPD) file. This allows some `distiller parameters`_ to be set when a PostScript file is generated. + +Windows XP or 2000 +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To install a "Ghostscript PDF" printer on Windows XP, select the Windows Control Panel, Printers and Faxes, Add a Printer, Local Printer, Use port FILE: (Print to File), Have Disk..., select the directory containing ghostpdf.ppd and ghostpdf.inf, select "Ghostscript PDF", Replace existing driver (if asked), and answer the remaining questions appropriately. After installing, open the "Ghostscript PDF" properties, select the Device Settings tab, set "Minimum Font Size to Download as Outline" to 0 pixels. + +To set distiller parameters, select the "Ghostscript PDF" Printing Preferences, then the Advanced button. The PDF settings are under "Printer Features". + + + +``pdfmark`` extensions +----------------------------------------- + +In order to better support the `ZugFERD electronic invoice standard`_ and potentially other standards in the future, a new non-standard ``pdfmark`` has been defined for use by pdfwrite. + +This ``pdfmark`` allows additional ``Metadata`` to be defined which will be inserted into the ``Metadata`` generated by the :title:`pdfwrite` device. This is necessary because the standard requires a PDF/A-3 file be produced, with an extension schema (and some additional XML data) contained within the ``Metadata`` referenced from the ``Catalog`` object. + +While it would be possible to use the existing ``Metadata`` ``pdfmark`` to write a completely new set of metadata into the ``Catalog``, creating a conformant set of XML, with all the information synchronised with the ``/Info`` dictionary would be challenging, this ``pdfmark`` allows the :title:`pdfwrite` device to generate all the normal information leaving the user with only the task of specifying the additional data. ``[ /XML (string containing additional XMP data) /Ext_Metadata pdfmark`` + + +Limitations +-------------------- + +The :title:`pdfwrite` family will sometimes convert input constructs to lower-level ones, even if a higher-level construct is available. For example, if the PostScript file uses ``charpath`` to set a clipping path consisting of text, :title:`pdfwrite` may write the clipping path as a path in the PDF file, rather than as text, even though PDF is able to express clipping with text. This is only a performance issue, and will be improved incrementally over time. + +Some applications, such as HIGZ, produce PostScript files that use ridiculously large coordinates. On such files, pdfwrite may cause a limitcheck error. If this occurs, try reducing the default internal resolution of 720 dpi by using the ``-r`` switch, e.g., ``-r300 somefile.ps``. + +:title:`pdfwrite` ignores the PDF 1.3 (Acrobat 4.x) ``pdfmarks`` related to document content structure: ``StRoleMap``, ``StClassMap``, ``StPNE``, ``StBookmarkRoot``, ``StPush``, ``StPop``, ``StPopAll``, ``StBMC``, ``StBDC``, ``EMC``, ``StOBJ``, ``StAttr``, ``StStore``, ``StRetrieve``, ``NamespacePush``, ``NamespacePop``, and ``NI``. While this causes some structural information to be omitted from the output file, the displayed and printed output are normally not affected. + + + +.. External links + +.. _MuPDF: https://mupdf.com +.. _IPA_2003-11_PDFX.pdf: http://www.color.org/IPA_2003-11_PDFX.pdf +.. _ZugFERD electronic invoice standard: http://www.ferd-net.de/front_content.php?idcat=231&changelang=4 + + + +.. include:: footer.rst + diff --git a/doc/src/_static/custom.css b/doc/src/_static/custom.css new file mode 100644 index 00000000..1d33520c --- /dev/null +++ b/doc/src/_static/custom.css @@ -0,0 +1,105 @@ +/* icon sizing in the left menu */ +.icon-home { + width: 100px; + height: auto; +} + +/* main document page: ensures pages fit to the available width and height */ +.wy-nav-content { + min-width: 100%; + min-height: 100vh; +} + +/* Accessibility: Artifex color for main document links */ +.wy-nav-content a { + color: #007aff; +} + +/* Artifex blue color for background elements */ +.wy-side-nav-search, .wy-nav-top { + background-color: #007aff; +} + +/* Accessibility: ensures that the version number is readable against the background color */ +.wy-side-nav-search>div.version { + color:hsla(0,0%,100%,1); +} + +h1, h2, h3, h4 { + padding: 10px; + border: 1px solid #007aff; + background-color: #007aff; + color: #fff; + border-radius: 5px; +} + +h1 a, h2 a, h3 a, h4 a { + color: #fff; +} + +cite { + font-family: monospace; + font-weight: bold; +} + + +button.cta { + -webkit-appearance: none; + -moz-appearance: none; + border:0; + text-transform:uppercase; + border-radius:5px; + font-size:16px; + font-weight:500; + min-height:40px; + line-height:40px; + padding: 0 15px; + color:#fff; + cursor:pointer; +} + +button.cta.orange { + width:auto; + background-image: linear-gradient(to right, #ea5842, #ec6343, #ed6d45, #ef7747, #f0804a) !important; +} + +button.cta.orange:hover { + background:#ea5842 !important; +} + +button.cta a { + color:#fff !important; +} + + +/* Dark mode colors */ +@media (prefers-color-scheme: dark) { + + + /* main document page */ + .wy-nav-content { + background-color: #000; + color: #fff; + } + + th { + color: #fff; + } + + td { + background-color: #000 !important; + } + + tr:nth-child(2n-1) td{ + background-color: #333 !important; + } + + pre { + color: #000; + } + + .admonition { + color: #000; + } + +} diff --git a/doc/src/_static/export-jar.png b/doc/src/_static/export-jar.png Binary files differnew file mode 100644 index 00000000..55550496 --- /dev/null +++ b/doc/src/_static/export-jar.png diff --git a/doc/src/_static/favicon.svg b/doc/src/_static/favicon.svg new file mode 100644 index 00000000..86b60ff9 --- /dev/null +++ b/doc/src/_static/favicon.svg @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 174.5 203" enable-background="new 0 0 174.5 203" xml:space="preserve"> + + <style>path{fill:#333}@media (prefers-color-scheme:dark){path{fill:#eee}}</style> + + <path d="M88.914,62.379c2.305-1.166-1.965-4.208-1.717-9.555c0.275-6.038,2.834-9.767-0.775-9.663 + c-2.843,0.078-7.028,5.283-6.347,10.597C80.771,59.059,85.951,63.869,88.914,62.379z"/> + <path d="M82.704,70.756c-2.901,1.852,4.552,3.786,6.338,9.383c2.024,6.331-0.215,10.913,5.012,9.777 + c4.119-0.888,8.132-7.467,5.004-12.756C95.923,71.864,86.422,68.364,82.704,70.756z"/> + <path d="M77.635,65.538c2.012-1.627-2.801-3.695-3.686-8.962c-1.002-5.985,0.72-10.149-2.799-9.292 + c-2.752,0.663-5.759,6.648-3.971,11.687C68.97,64.008,75.064,67.635,77.635,65.538z"/> + <g> + <path d="M8.34,182.553c8.033,8.36,27.344,18.325,73.727,18.325c77.712,0,86.343-34.936,86.672-36.423l0.074-0.335 + l-2.615-0.673l-0.103,0.317c-0.084,0.262-9.182,26.392-76.57,26.392c-2.336,0-4.77-0.032-7.237-0.095 + c-16.732-0.429-30.657-3.138-40.269-7.831c-8.394-4.1-13.017-9.442-13.017-15.044c0-11.862,13.986-12.627,14.581-12.655 + l0.316-0.015l0.177-2.639l-0.312-0.057c-0.233-0.042-5.807-1.036-12.745-1.036c-18.07,0-28.293,6.655-28.786,18.739 + C2.206,170.181,2.159,176.119,8.34,182.553z"/> + <path d="M152.435,59.232c1.118-13.45-11.403-23.37-15.267-26.09l-0.155-0.109l0.021-0.188 + c0.952-8.478-0.737-15.52-5.021-20.929c-6.977-8.81-18.449-10.085-18.934-10.135l-0.328-0.033l-0.437,2.648l0.32,0.077 + c0.518,0.124,12.73,3.157,14.018,14.733c1.131,10.18-6.367,14.962-13.618,19.586c-5.594,3.572-10.871,6.942-10.871,12.57 + c0,6.214,5.439,10.593,10.7,14.827c5.32,4.281,10.341,8.321,9.969,13.87c-0.687,10.304-20.492,15.748-20.692,15.802l-0.331,0.088 + l0.568,2.639l0.333-0.054C143.685,91.88,151.452,71.054,152.435,59.232z"/> + <path d="M80.146,181.454c4.818,0.771,10.645,1.179,16.85,1.179c16.754,0,39.861-3.118,54.467-11.867 + c14.401-8.616,16.364-22.548,10.86-31.856v-0.001c-4.971-8.418-20.259-22.757-66.8-24.202 + c-32.475-0.997-48.941-3.565-48.941-7.633c0-3.392,5.788-4.433,11.916-5.535c7.688-1.384,16.401-2.954,16.174-10.354 + c-0.145-4.691-4.298-7.432-9.107-10.607c-7.262-4.8-16.297-10.773-14.116-26.241c1.864-13.148,21.14-18.701,29.341-20.478 + c11.723-2.537,31.451-8.128,31.858-17.067c0.368-8.21-8.415-10.998-8.503-11.025l-0.304-0.095l-0.915,2.059l-0.194,0.336 + l0.304,0.179c0.152,0.092,3.643,2.253,2.214,6.375c-1.521,4.398-7.704,4.754-25.358,5.137 + c-17.544,0.386-39.579,2.793-54.373,18.103c-8.041,8.324-11.314,19.207-8.754,29.112c2.713,10.485,11.718,19.235,25.356,24.64 + l0.913,0.362l-0.951,0.245c-3.259,0.838-8.195,2.305-13.196,4.529c-12.741,5.665-19.313,13.407-19.004,22.39 + c0.797,22.879,35.182,26.661,68.713,27.343c35.983,0.731,51.335,4.303,51.335,11.942c0,6.147-11.885,11.023-28.26,11.596 + c-1.88,0.065-3.719,0.097-5.466,0.097c-10.907,0-17.937-1.091-21.914-2.007c-4.734-1.088-7.577-2.501-7.606-3.777 + c-0.015-0.593,0.165-1.072,0.55-1.467c1.375-1.41,4.781-1.706,7.397-1.706c3.296,0,6.365,0.481,6.704,0.535l0.315,0.052 + l0.748-2.53l-0.29-0.125c-0.064-0.027-6.083-2.606-14.252-2.606c-0.505,0-1.018,0.01-1.539,0.031 + c-6.817,0.301-11.677,3.807-11.819,8.526C54.379,168.728,56.635,177.698,80.146,181.454z"/> + </g> + +</svg> diff --git a/doc/src/_static/ghostnet-wpf-example.png b/doc/src/_static/ghostnet-wpf-example.png Binary files differnew file mode 100644 index 00000000..b5b1eaa1 --- /dev/null +++ b/doc/src/_static/ghostnet-wpf-example.png diff --git a/doc/src/_static/ghostscript-white-plus-text.png b/doc/src/_static/ghostscript-white-plus-text.png Binary files differnew file mode 100644 index 00000000..436fd6f3 --- /dev/null +++ b/doc/src/_static/ghostscript-white-plus-text.png diff --git a/doc/src/_static/gsviewer.png b/doc/src/_static/gsviewer.png Binary files differnew file mode 100644 index 00000000..75c9d5af --- /dev/null +++ b/doc/src/_static/gsviewer.png diff --git a/doc/src/_static/linking-jar.png b/doc/src/_static/linking-jar.png Binary files differnew file mode 100644 index 00000000..ce64e587 --- /dev/null +++ b/doc/src/_static/linking-jar.png diff --git a/doc/src/conf.py b/doc/src/conf.py new file mode 100644 index 00000000..d4c6487e --- /dev/null +++ b/doc/src/conf.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- +# +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath(".")) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = "4.2.0" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +# extensions = ["sphinx.ext.autodoc", "sphinx.ext.coverage", "sphinx.ext.ifconfig"] +# +# Note on :sphinx.ext.autosectionlabel +# this is handy as it adds link ids to your labels and easy referencing +# However the downside is the build will report many warnings for "duplicate labels", +# not a problem as the benefits outweigh the hassle of adding unique section +# links everywhere +# +extensions = [ + 'rst2pdf.pdfbuilder', + 'sphinx.ext.autosectionlabel' +] +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix of source filenames. +source_suffix = ".rst" + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = "toc" + +# General information about the project. +project = "Ghostscript" +copyright = "1988-2022, Artifex" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = "10.0.0" + +# The short X.Y version +version = release + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "sphinx_rtd_theme" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] +# html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = "_static/ghostscript-white-plus-text.png" + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = "_static/favicon.svg" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# A list of CSS files. The entry must be a filename string or a tuple containing +# the filename string and the attributes dictionary. The filename must be +# relative to the html_static_path, or a full URI +html_css_files = ['custom.css'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = "%d. %b %Y" + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = False + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +html_additional_pages = {} + +# If false, no module index is generated. +html_domain_indices = True + +# If false, no index is generated. +html_use_index = True + +# If true, the index is split into individual pages for each letter. +html_split_index = True + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False +html_sourcelink_suffix = ".rst" +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +html_use_opensearch = "" + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +html_file_suffix = ".html" + +# Output file base name for HTML help builder. +htmlhelp_basename = "Ghostscript" + + +# -- Options for LaTeX output --------------------------------------------- +latex_elements = { + # "fontpkg": r"\usepackage[sfdefault]{ClearSans} \usepackage[T1]{fontenc}" +} +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ("index", "Ghostscript.tex", u"Ghostscript Documentation", u"Artifex", "manual") +] +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = "_static/ghostscript-white-plus-text.png" + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = True +# latex_use_xindy = True +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +latex_domain_indices = True + +# -- Options for PDF output -------------------------------------------------- +# Grouping the document tree into PDF files. List of tuples +# (source start file, target name, title, author). + +pdf_documents = [("index", "Ghostscript", "Ghostscript Manual", "Artifex")] + +# A comma-separated list of custom stylesheets. Example: +#pdf_stylesheets = ["sphinx", "bahnschrift", "a4"] + +# Create a compressed PDF +pdf_compressed = True + +# A colon-separated list of folders to search for fonts. Example: +# pdf_font_path=['/usr/share/fonts', '/usr/share/texmf-dist/fonts/'] + +# Language to be used for hyphenation support +pdf_language = "en_US" + +# If false, no index is generated. +pdf_use_index = True + +# If false, no modindex is generated. +pdf_use_modindex = True + +# If false, no coverpage is generated. +pdf_use_coverpage = True + +pdf_break_level = 2 + +pdf_verbosity = 0 +pdf_invariant = True diff --git a/doc/src/footer.rst b/doc/src/footer.rst new file mode 100644 index 00000000..de227efd --- /dev/null +++ b/doc/src/footer.rst @@ -0,0 +1,7 @@ + +.. raw:: html + + <hr> + +This software is provided AS-IS with no warranty, either express or implied. This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of that license. Refer to licensing information at https://www.artifex.com or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. + diff --git a/doc/src/index.rst b/doc/src/index.rst new file mode 100644 index 00000000..7f001d40 --- /dev/null +++ b/doc/src/index.rst @@ -0,0 +1 @@ +.. include:: Readme.rst
\ No newline at end of file diff --git a/doc/src/requirements.txt b/doc/src/requirements.txt new file mode 100644 index 00000000..fb3c028e --- /dev/null +++ b/doc/src/requirements.txt @@ -0,0 +1 @@ +rst2pdf diff --git a/doc/src/thirdparty.rst b/doc/src/thirdparty.rst new file mode 100644 index 00000000..855ed485 --- /dev/null +++ b/doc/src/thirdparty.rst @@ -0,0 +1,212 @@ +.. title:: Third Party Libraries Used by Ghostscript and GhostPDL + +.. meta:: + :description: The Ghostscript documentation + :keywords: Ghostscript, documentation, ghostpdl + + +.. _thirdparty.htm: + + +Third Party Libraries Used by Ghostscript and GhostPDL +========================================================= + + +The table below details the third party libraries that Ghostscript and/or GhostPDL include, the versions QA tested and shipped with our releases, the relevant license, and the "upstream" URL. + + +.. list-table:: + :header-rows: 1 + :widths: 20 10 25 25 20 + + * - Library Name + - Version + - Function + - License + - URL + * - CUPS + + (AGPL Release Only) + + - 2.8.0 + - CUPS raster format output + - GPL Version 3 + - http://www.cups.org/ + * - eXpat + - 2.4.1 + - XML parsing for XPS interpreter + - MIT/eXpat License + - http://expat.sourceforge.net/ + * - FreeType + - 2.12.1 + - Font scaling and rendering + + for Ghostscript + - FreeType License + + (BSD-style license + + with a credit clause) + + - http://www.freetype.org/ + * - jbig2dec + - 0.19 + - JBIG2 decoding for the + + PDF interpreter + - Licensed with Ghostscript/GhostPDL + + (copyright owned by Artifex) + + - http://www.ghostscript.com/ + * - libjpeg + - 9e with patches + - JPEG/DCT decoding/encoding + - "Free" Can be used in + + commercial applications + + without royalty, + + with acknowledgement. + - http://www.ijg.org/ + * - LittleCMS2 mt + + (lcms2mt - thread + + safe fork of lcms2) + + - 2.10mt + - ICC profile based color conversion + + and management + + - MIT LICENSE + - http://www.ghostscript.com/ + * - libpng + - 1.6.37 + - PNG image encoding/decoding + - libpng license - classified as + + "a permissive free software license" + - http://www.libpng.org/ + * - OpenJPEG + - 2.4.0 + - JPEG2000 image decoding for the + + PDF interpreter + + - BSD-style + - http://www.openjpeg.org/ + * - zlib + - 1.2.12 + - (De)Flate compression + - zlib license - classified as + + "a permissive free software license" + - http://www.zlib.net/ + * - libtiff + - 4.3.0 + - TIFF image encoding/decoding + - BSD-style + - http://www.remotesensing.org/libtiff + + +The following are optional. + + + +.. list-table:: + :header-rows: 1 + :widths: 20 10 25 25 20 + + * - Library Name + - Version + - Function + - License + - URL + * - tesseract + - 4.1.0 + with patches + - Optical Character Recognition (OCR) library + - Apache License 2.0 + - https://github.com/tesseract-ocr/tesseract + * - leptonica + - 1.80.0 with patches + - Image processing toolkit - support + + library for tesseract OCR + + - Leptonica License + + "a permissive free software license" + + - http://www.leptonica.org/ + + + + +The following are no-cost, open source licensed, but not GPL compatible. + + + +.. list-table:: + :header-rows: 1 + :widths: 20 10 25 25 20 + + * - Library Name + - Version + - Function + - License + - URL + * - jpegxr (JPEG XR reference software) + - 1.8 + - HDPhoto/JPEG-XR image + + decoding for the XPS interpreter + - ITU/ISO/IEC "Free" License + + Reference implementation + - http://www.itu.int/rec/T-REC-T.835 + + + + +The following is optional & relevant to Artifex Software commercial releases only. + + +.. list-table:: + :header-rows: 1 + :widths: 20 10 25 25 20 + + * - Library Name + - Version + - Function + - License + - URL + * - Monotype UFST + - 5.x/6.x with patches + - Access, scale and render + + Monotype MicroType fonts + - Commercial + - https://www.monotype.com/ + + + + + + + + + + + + + + + + + + +.. include:: footer.rst diff --git a/doc/src/toc.rst b/doc/src/toc.rst new file mode 100644 index 00000000..e02c9656 --- /dev/null +++ b/doc/src/toc.rst @@ -0,0 +1,38 @@ +Table of Contents +======================================== + +.. toctree:: + + Readme.rst + Make.rst + Install.rst + Use.rst + API.rst + LanguageBindings.rst + Devices.rst + VectorDevices.rst + Drivers.rst + Language.rst + Lib.rst + Develop.rst + C-style.rst + Ps-style.rst + Ps2epsi.rst + Psfiles.rst + Fonts.rst + Unix-lpr.rst + News.rst + Source.rst + thirdparty.rst + UnsupportedDevices.rst + + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/doc/style.css b/doc/style.css deleted file mode 100644 index 8978b867..00000000 --- a/doc/style.css +++ /dev/null @@ -1,433 +0,0 @@ -@charset "UTF-8"; -/* CSS Document */ - -* { - box-sizing: border-box; - } - -.row::after { - content: ""; - clear: both; - display: table; - } - -[class*="col-"] { - float: left; - } - -.col-1 {width: 10%;} -.col-2 {width: 16.66%;} -.col-3 {width: 25%;} -.col-4 {width: 33.33%;} -.col-ft-3 {width: 20%;} -.col-5 {width: 41.66%;} -.col-6 {width: 50%;} -.col-lt-6 {width: 50%;} -.col-7 {width: 58.33%;} -.col-8 {width: 55%;} -.col-9 {width: 55%;} -.col-10 {width: 83.33%;} -.col-11 {width: 91.66%;} -.col-12 {width: 100%;} - -body { - font-family: "Source Sans Pro", sans-serif; - margin-left: auto; - margin-right: auto; - margin-top: 0px; - margin-bottom: 0px; - max-width: 1200px; - } -p { - color: #333333; - font-size: 14px; -} - -dt { - font-weight: 600; - } - -h1 { - margin-top: 0px; - margin-bottom: 14px; - font-size: 24px; - font-weight: 600; - color: #565656; - } - -h2 { - font-size: 22px; - font-weight: 600; - color: #565656; - } - -h3 { - font-size: 18px; - font-weight: 600; - color: #565656; - } - -h4 { - font-size: 16px; - font-weight: 400; - color: #565656; - } - -h5 { - font-size: 16px; - font-weight: 400; - color: #565656; - } - -pre { - font-family: "Source Code Pro", Consolas, "Andale Mono", Monaco, monospace; - color: #565656; - font-size: 14px; - } - -code { - font-family: "Source Code Pro", Consolas, "Andale Mono", Monaco, monospace; - color: #565656; - font-size: 14px; - } - -a { - color: #0068BD; - text-decoration: none; - font-size: 14px; - } - -a:visited { - color: #007FE7; - text-decoration: none; - } - -a:hover { - text-decoration: underline; - } - -ul li { - list-style-type: disc; - font-size: 14px; - padding-right: 12px; - color: #666; - } - -hr { - color: #e6e6e6; - background-color: #e6e6e6; - height: 2px; - border: none; - } - -.header { - width: 100%; - padding: 10px 20px 10px 15px; - } - -.artifexlogo { - padding: 25px 8px 10px 0px; - float: right; - } - -.button { - float: right; - border: none; - border-radius: 4px; - color: #fff; - text-align: center; - width: 100px; - -webkit-transition-duration: 0.4s; /* Safari */ - transition-duration: 0.4s; - cursor: pointer; - padding: 8px 10px; - display: inline; - } - -.button a { - color: #fff; - font-size: 16px; - text-decoration: none; - } - -.button2 { - background-color: #00b3e3; - margin-right: 5px; - } - -.button2:hover { - background-color: #0075cf; - text-decoration: none; - } - -.button2:visited { - background-color: #00b3e3; - } - -.button1 { - background-color: #77c11f; - float: right; - } - -.button1:hover { - background-color: #009818; - text-decoration: none; - } - -.button1:visited { - background-color: #77c11f; - } - -.banner { - background-color: #506B80; - font-size: 20px; - font-weight: 400; - color: #fff; - padding: 20px 0px 20px 15px; - } - -.main { - width: 100%; - } - -.page { - font-size: 14px; - padding: 15px 10px 15px 25px; - } - -.leftnav { - background-color: #f0f0f0; - list-style-type: none; - padding-left: 8px; - } - -.leftnav ul { - list-style-type: none; - margin: 0; - padding: 0; - background-color: #f0f0f0; - } - -.leftnav li { - font-size: 14px; - list-style-type: none; - } - -.leftnav li a { - list-style-type: none; - display: block; - color: #000; - padding: 11px 11px; - } - -.leftnav li a:hover { - background-color: #555; - text-decoration: none; - color: #fff; - } - -.footer { - background-color: #f1f1f1; - padding: 10px 0px; - font-size: 9px; - color: #333; - margin: 0px; - } - -.footer li { - color: #333; - list-style-type: none; - padding-bottom: 5px; - } - -.footer li a { - font-size: 11px; - list-style-type: none; - color: #333; - } - -.footer li a:hover { - color: #666; - text-decoration: none; - } - -.footleft { - text-align: right; - } - -.footcenter { - text-align: left; -} - -.footright { - padding: 10px 0px 0px 0px; - margin: 0px 20px 0px 40px; -} - -.col-ft-3 img { - max-width: 150px; - max-height: 31px; - } - -.accordion { - background-color: #f0f0f0; - color: #444; - cursor: pointer; - padding: 18px; - width: 75%; - border: none; - text-align: left; - outline: none; - font-size: 15px; - transition: 0.4s; - margin-bottom: 10px; -} - -.active, .accordion:hover { - background-color: #ccc; -} - -.accordion:after { - content: '\002B'; - color: #777; - font-weight: bold; - float: right; - margin-left: 5px; -} - -.active:after { - content: "\2212"; -} - -.panel { - padding: 0 18px; - background-color: white; - max-height: 0; - width: 75%; - overflow: hidden; - transition: max-height 0.2s ease-out; -} - -.menuTrigger {display:none;} -@media screen and (min-width: 480px){ -#sidebar {display:block!important} -} -@media screen and (max-width: 480px){ - -#sidebar{display:none;} - -.menuTrigger {display:block; background-color: #506b80;} -.menuTrigger:before{content: url(images/hamburger-light.png); padding: 9px 0px 6px 18px; background: #506b80; display: inline-block; } -.menuTrigger.selected:before{content:url(images/x-light.png); } - -} - -/*TABLET*/ -@media (max-width:768px){ - -.col-1 {width: 25%;} -.col-2 {width: 25%;} -.col-ft-3 {width: 30%;} -.col-7 {width: 30%;} -.col-10 {width: 75%;} - -.col button button1 button2 { - display: inline; - } - -.footright { - padding: 10px 0px 10px 0px; - margin-right: 10px; } - -.col-ft-3 img { - max-width: 130px; - max-height: 27px; - } - -.hidden-lg { - display: none; - } -} - -/*MOBILE*/ -@media (max-width:480px){ - -.col-1 {width: 50%;} -.col-2 {width: 100%;} -.col-ft-3 {width: 50%;} -.col-6 {width: 50%;} -.col-7 {width: 50%;} -.col-10 {width: 100%;} - -.col-6 img { - max-width: 150px; - max-height: 31px; - } - -.col-lt-6 img { - max-width: 79px; - max-height: 85px; - } - -.col-ft-3 img { - max-width: 125px; - max-height: 25px; - } - -h1 { - font-size: 22px; - } - -h2 { - font-size: 16px; - } - -h3 { - font-size: 14px; - } - -.header { - margin: 0px; - } - -.hidden-xs { - display: none; - } - -.hidden-lg { - display: inline; - } - -.logo { - padding: 0px 0px 0px 0px; - } - -.artifexlogo { - padding: 15px 0px 5px 10px; - } - -.footright { - padding: 10px 0px 0px 0px; - } - -.button { - padding: 4px 10px 5px; - font-size: 13px; - margin-right: 6px; - } - -.banner { - background-color: #506B80; - font-size: 18px; - font-weight: 400; - color: #fff; - padding: 5px 0px 0px 18px; - } -} - -/*DESKTOP*/ -@media (min-width:769px){ - .hidden-lg { - display: none; - } -} diff --git a/doc/subclass.htm b/doc/subclass.htm deleted file mode 100644 index 0c8dd527..00000000 --- a/doc/subclass.htm +++ /dev/null @@ -1,722 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Ghostscript: Device Subclassing</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Ghostscript: Device Subclassing</h1> - -<h2><a name="toc"></a>Table of contents</h2> -<ul class="toc"> - <li><a href="#Gstate">Devices in the graphcis state</a></li> - <li><a href="#Chaining">Chaining devices</a></li> - <li><a href="#Subclassing">Subclassing</a></li> - <li><a href="#Example_uses">Example uses</a></li> - <li><a href="#Observations">Observations</a></li> - <li><a href="#Example">Worked example</a></li> -</ul> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.0 end visible header] ============================================== --> - -<!-- [2.0 begin contents] ================================================== --> -<hr> -<h2><a name="Gstate"></a>Devices in the graphics state</h2> -<p> -The 'device' is a member of the graphics state in PostScript, and is subject to gsave/grestore, like - any other part of the graphics state. This is important for PostScript as it allows us to, for - example, push the null device, perform some operations, and then grestore back to the original rendering - device. -</p><p> -In PostScript and PDF, the graphics state is itself a garbage collected object, as is the device. This - means that we store a pointer to the device in the graphics state, which forces the other interpreters - to do so as well. Now an important implication of this is that it is then only possible, currently, to - change devices by altering the graphics state entry to point at a different device structure, which - means that the graphics state must be available in order to do so. Clearly at the interpreter level this - isn't a problem, but at lower levels the graphics state may not be available, not all our device methods - pass on a graphics state pointer for example. Without that pointer we can't change the graphics state and - therefore can't point at a different device. -</p> -<hr> -<h2><a name="Chaining"></a>Chaining devices</h2> -<p> -There are times when it is useful to be able to chain devices one after another, examples include the PDF - transparency device, the pattern accumulator device and others. Some comments in early code indicate that - the ability to chain devices was an original design goal, though its likely that originally this was only - intended to work by installing devices from the interpreter level. -</p><p> -Currently there are a number of different ways to install devices, and the sheer number, and the methods - themselves, show why there is a problem. Lets consider them separately. -</p> -<p> -<dd> -Forwarding devices. These devices generally intercept the usual graphics marking operations, and pass them - on to the underlying device, or record some features of interest. Examples of these include the bbox device - and the pattern accumulator. These work very well, but require the graphics state to be available when we - need to insert them ahead of the 'underlying' device. This can be a problem, as we'll see later. -</dd> -</p><p> -<dd> -The device filter stack. This appears to be an early attempt at providing a way to chain devices together. - From traces remaining in the code this seems to originally have been intended to implement the PDF 1.4 - transparency rendering. Its clear, however, that it is no longer used for that purpose and appears to be - completely redundant. In any event it also requires access to the graphics state and so would suffer the - same limitation. -</dd></p> -<p><dd> -The clist. The clist code uses a very brute force approach to the problem, and only works for a single device. - When a device is turned into a clist device, the code essentially guts the device and rewrites it (it replaces - the overwritten entries later). This does work (though it seems rather horrendous to me) and doesn't require - access to the graphics state because we simply reuse the existing memory of the original device. However this - doesn't get us a 'chain', the clist simply morphs the existing device into something different. -</dd></p> -<p><dd> -The PDF transparency compositor. This works in several ways to install itself, but the one of most interest is - the case where we return from the device 'create_compositor' method. The interpreter is required to treat the - return value as a pointer to a device, and if its not the same as the device currently in the graphics state, - then it alters the graphics state to point to the new device. I'm not sure why its done this way as we do - actually have access to the graphics state in this method and could presumably install the device ourselves. - However it is not useful as a general purpose method for installing devices as it requires the return value - to be acted upon by the interpreter. Making this general would require us to modify all the existing device - methods, and have the interpreters check the return value, it would almost certainly be simpler (and more useful) - to alter the methods to always include a graphics state. -</dd></p> -<p><dd> -The 'spy' device. This is a somewhat non-standard device written by Robin, it works by copying the pointer to the - device methods, and then replacing all the device methods, it is thus very similar to the clist device. -</dd></p> -<p> -Taken together we have a number of different routes to install devices, but none of them is totally satisfactory - for the goal of creating a chain of devices without access to the graphics state. However I think the existence of - these manifold routes do indicate that there has been a recognition in the past that this would be useful to have. -</p> -<hr> -<h2><a name="Subclassing"></a>Subclassing</h2> -<p> -From the above, its clear that we need to use some approach similar to the clist and spy devices. We must retain - the original device memory, because that is what the graphics state points to, which means that we must reuse that - memory in some fashion. By making a copy of the existing device elsewhere, we can then recycle the existing device. -</p><p> -As a short summary, that's precisely what the device subclassing code does. It examines the existing device, makes - a new device structure sufficiently large to take a copy of it, and copies the existing device and all its state to - that new memory. It then uses the prototype supplied for the new class, and writes that into the original device memory. -</p> -<h4>New device members</h4> -<p> -In order to chain the devices together, I've added three new pointers to the device structure (so that all devices - can be chained), a child, a parent and a 'data' pointer (see below). Whenever we subclass a device the copied device - gets its parent member set to the original device pointer, and the new device points to the copied one using the child - member.</p> -<p> -Now a subtle point here is that, because we cannot change the size of the memory allocated for the original device - (as that might relocate it, invalidating the graphics state pointer) its absolutely vital that the new device must be no - larger than the old device. This means we have to be careful about data which the new device needs, we can't simply store - it in the device structure as we usually do. To resolve that I've also added a void pointer to hold private data, the new - device should allocate as much data as it requires (eg a structure) and store a pointer to that data in the subclass_data - pointer. I'd recommend that this is allocated from non-GC memory except in special cases. This should mean that subclassing - devices are never larger than a gx_device structure and so never overflow. -</p> -<h4>Subclassing made easy</h4> -<p> -In order to minimise the number of methods that a subclassing device needs to define I've created 'default' methods for all - the possible device methods. Subclassing devices should use these in their prototype for any methods they don't handle. - Additionally these can be used to pass on any methods after processing by the subclassing device, if required. -</p> -<hr> -<h2><a name="Example_uses"></a>Example uses</h2> -<p> -The original justification for this work was to create a device which would add 'first page' and 'last page' functionality - to all the languages and all the devices. The gdevflp.c file incorporates exactly that, it has been added to gdevprn.c and - gdevvec.c so that any device based on either of these two basic devices will simply work. Additionally other devices which - are not based on either of these (eg the 'bit' device) have been appropriately modified. -</p> -<p> -If <code>-dFirstPage</code> or <code>-dLastPage</code> is set the parameter is parsed out and the existing device is - subclassed by the new First/Last page device. This device simply drops all marking operations, and 'output_page' operations - until we reach the page defined by FirstPage, and then passes everything through to the real device until we pass the page - defined by LastPage at which point it throws everything away again until the end of the input. -</p> -<p> -Now, this is not as efficient as the PDF interpreter's usage, which only passes those pages required to be rendered. So the - old functionality has been preserved in the PDF interpreter, exactly as before. In order to prevent the subclassing device - addionally acting on the same parameters, there is a <code>DisablePageHandler</code> flag which is set by the PDF interpreter. -</p> -<p> -In order to test the chaining of devices together, I also created an 'object filtering' device; as with the first/last page - device this has been added to all devices and any device based off gdevprn or gdevvec should inherit the functionality - directly. This device allows objects to be dropped based on their type (text, image or linework) using the parameters - <code>-dFILTERTEXT -dFILTERIMAGE</code> and <code>-dFILTERVECTOR</code>, if a parameter is set then objects of that type - will not be rendered. -</p> -<p> -Finally the PCL interpreter now uses a subclassing device to implement the 'monochrome palette' rendering. Previously this - directly modified the color_procs in the current device, which I suspect was prone to potential failure (for example if a - forwarding device had been pushed). This eliminated a somewhat ugly hack (in fairness its not obvious what would have been - better), as well as allowing me to do away with some global variables in the PCL interpreter. -</p> -<hr> -<h2><a name="Observations"></a>Observations</h2> -<p> -The monochrome palette device illuminated an interesting problem in the graphics library. Normally the device calls the graphics - library for rendering services, but the color_procs work in reverse, the graphics library calls the device directly in order to - map the colours. In the case of chained devices this meant that only the final device was being called. This was unacceptable in - a situation involving chained devices, it seemed obvious to me that the graphics library should pass the request to the head of - the device chain for processing. There is no simple way to do this (no access to the graphics state!) so instead I used the linked - list of child/parent pointers to walk up to the head of the list, and then submit the request to that device. -</p> -<p> -The ICC profile code has a 'get_profile' method in the device API to retrieve a profile, but it has no corresponding 'set_profile' - method, it simply sets the structure member in the current device. This caused some serious problems. Consider the case where the - ICC code executes a get_profile and no profile is yet set (returning NULL). The code would then create a profile and attach it - directly to the current device. It then executes 'get_profile' again. If the current device was a subclassing device, or a forwarding - device, then the 'set' would have set the profile in that device, but the 'get' would retrieve it from the underlying device, which - would still be NULL. Since the ICC code didn't test the result on the second call this caused a segmentation fault. I've modified - the ICC code to set the profile in the lowest device, but this probably ought to be improved to define a new 'set_profile' method. -</p> -<p>The tag devices write an extra colour plane in the output, where the value of the sample encodes the type of graphic that was - rendered at that point (text, image, path, untouched or unknown). This is done by encoding the type in the color, which is performed - by the graphics library. Now, when the type of operation changes (eg from image to text) we need to tell the graphics library that - there has been a change. We do this by calling the set_graphics_type_tag device method. However, when encoding a color, the graphics - library does not, as one might expect call a matching get_graphics_type method, instead it directly inspects the devcie structure and - reads the graphics_type_tag member. This means that all devices in the chain must maintain this member, the implication is that if - a subclassing device should implement its own set_graphics_type_tag method, it must update the graphics_type_tag in its device - structure appropriately, and pass the method on to the next device in the chain. The default method already does this.</p> -<p> -Its pretty clear from reading through the code that the original intention of the device methods is that all methods in a device - should be filled in, they should never be NULL (exception; fill_rectangle is deliberately excluded from this) if a device does not - implement a method then 'fill_in_procs' should set a default method (which may legitimately simply throw an error). Over time this - decision has not been enforced with the result that we now have some places where methods may be NULL. This has meant that there - are places in the code which have to check for a method being NULL before using it, which is (I think) exactly what we were - originally trying to avoid. Worse, since there is no list of which methods may be NULL a sensible developer would have to test all - methods before use. Worst of all, it looks like some places may take a NULL method as having specific meaning (gsdparam.c line 272). - We should really tidy this up. - </p> -<p> -General observations are recorded in comments in gdevsclass.c -</p> -<hr> -<h2><a name="Example"></a>Worked example</h2> -<p> -To see how to use the device subclassing we'll take a concrete example and implement it in a real device. For the purposes of the - example we'll do a 'force black text' device and add it to the TIFF device(s). The reason for choosing the TIFF devices is that - these already have an 'open_device' method which we are going to use to install the subclassing device. This isn't essential, - you could install the device at any point, but its convenient. -</p> -<p> -The first thing we need to do is add some control to turn this feature off and on, this is normally done by setting device - parameters on the command line. To implement this we will need to modify the put_params and get_params methods. Note it is - important to add new parameters to both the get and put methods, or an error will occur. We'll call our new parameter - <code>ForceBlackText</code>. -</p> -<p> -First we add the new parameter to the TIFF device, defined in gdevtifs.h: -</p> -<code> -typedef struct gx_device_tiff_s { -<dd> gx_device_common;<br /> - gx_prn_device_common;<br /> - bool ForceBlackText;<br /> - bool BlackTextHandlerPushed;<br /> -.... -</dd> -}<br /> -</code><p> -Note that we also have a boolean value 'BlackTextHandlerPushed' to track whether the device is already pushed or not, we'll want to use this later. -</p> -<p> -We also need to add default values to the device prototypes, which are defined in gdevtfnx.c: -</p> -<code>const gx_device_tiff gs_tiff12nc_device = { -<dd> prn_device_std_body(gx_device_tiff, tiff12_procs, "tiff12nc",<br /> - DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,<br /> - X_DPI, Y_DPI,<br /> - 0, 0, 0, 0,<br /> - 24, tiff12_print_page),<br /> - 0, /* ForceBlacktext */<br /> - 0, /* BlacktextHandlerPushed */<br /> - arch_is_big_endian /* default to native endian (i.e. use big endian iff the platform is so*/, -</dd> -</code><p> -Repeat for gs_tiff24nc_device and gs_tiff48nc_device. For unknown reasons, the remaining TIFF devices are in gdevtsep.c, we need to make the - same changes to the prototypes there; gs_tiffgray_device gs_tiffscaled_device gs_tiffscaled8_device gs_tiffscaled24_device - gs_tiffscaled32_device gs_tiffscaled4_device gs_tiff32nc_device gs_tiff64nc_device and finally tiffsep_devices_body. -</p> -<p>Now we add code to put_params and get_params to set the parameter, and report its value back to the interpreter. In gdevtifs.c:</p> -<code>static int -tiff_get_some_params(gx_device * dev, gs_param_list * plist, int which)<br /> -{ -<dd> gx_device_tiff *const tfdev = (gx_device_tiff *)dev;<br /> - int code = gdev_prn_get_params(dev, plist);<br /> - int ecode = code;<br /> - gs_param_string comprstr;<br /> -<br /> - if ((code = param_write_bool(plist, "ForceBlackText", &tfdev->ForceBlackText)) < 0)<br /> - ecode = code;<br /> -.... -</dd> -} -</code> -<code> -<br />static int -tiff_put_some_params(gx_device * dev, gs_param_list * plist, int which)<br /> -{ -<dd>gx_device_tiff *const tfdev = (gx_device_tiff *)dev; - int ecode = 0;<br /> - int code;<br /> - const char *param_name;<br /> - bool big_endian = tfdev->BigEndian;<br /> - bool usebigtiff = tfdev->UseBigTIFF;<br /> - uint16 compr = tfdev->Compression;<br /> - gs_param_string comprstr;<br /> - long downscale = tfdev->DownScaleFactor;<br /> - long mss = tfdev->MaxStripSize;<br /> - long aw = tfdev->AdjustWidth;<br /> - long mfs = tfdev->MinFeatureSize;<br /> - bool ForceBlackText = tfdev->ForceBlackText;<br /> -<br /> - /* Read ForceBlackText option as bool */<br /> - switch (code = param_read_bool(plist, (param_name = "ForceBlackText"), &ForceBlackText)) {<br /> - default:<br /> - ecode = code;<br /> - param_signal_error(plist, param_name, ecode);<br /> - case 0:<br /> - case 1:<br /> - break;<br /> - }<br /> -<br /> - /* Read BigEndian option as bool */<br /> - switch (code = param_read_bool(plist, (param_name = "BigEndian"), &big_endian)) {<br /> -</dd>... -<dd> tfdev->MinFeatureSize = mfs;<br /> - tfdev->ForceBlackText = ForceBlackText;<br /> - return code;<br /> -</dd>} -</code> -<p> -Checking the TIFF device's open method (tiff_open) we see that it already potentially has two subclassing devices, - this is because it doesn't inherit from gdev_prn, if it did this functionality would be inherited as well. We can - just go ahead and add our new subclassing device in here. -</p> -<br /> -<code>int -tiff_open(gx_device *pdev)<br /> -{ -<dd> gx_device_printer * const ppdev = (gx_device_printer *)pdev;<br /> - gx_device_tiff *tfdev = (gx_device_tiff *)pdev;<br /> - int code;<br /> - bool update_procs = false;<br /> -<br /> - /* Use our own warning and error message handlers in libtiff */<br /> - tiff_set_handlers();<br /> -<br /> - if (!tfdev->BlackTextHandlerPushed && (tfdev->ForceBlackText != 0)) {<br /> - gx_device *dev;<br /> -<br /> - gx_device_subclass(pdev, (gx_device *)&gs_black_text_device, sizeof(black_text_subclass_data));<br /> - tfdev = (gx_device_tiff *)pdev->child;<br /> - tfdev->BlackTextHandlerPushed = true;<br /> -<br /> - while(pdev->child)<br /> - pdev = pdev->child;<br /> - pdev->is_open = true;<br /> - update_procs = true;<br /> - }<br /> -</dd> -</code><p> -You might notice that this is a little simpler than the other device installations, that's because the other devices can potentially - be installed by any device, and we need to track them more carefully. Our new device can only be installed by the TIFF device, so we - don't need to note that its been installed already, in all the parent and child devices. This is only done so that we don't - accidentally install these more basic devices more than once. -</p> -<p> -So the first thing we do is check to see if we've already installed the device to force black text (we can potentially call the open - method more than once and we don't want to install the device multiple times). If we haven't installed the device yet, and the feature - has been requested, then we call the code to subclass the current device using the 'black_text_device' as the prototype for the new - device, and pass in the amount of data it requires for its private usage. -</p> -<p> -We will be defining this device as the next steps, for now just notice that after we call this, the 'current' device in the graphics - state will be the black_text_device, and its 'child' member will be pointing to the TIFF device. So we note in that child device that - we have pushed the black text handling device. We also note that the TIFF device is 'open' (the calling code will do this for the - device pointed to by the graphics state, ie the black text device). Finally we set a boolean to 'update procs'. This is needed because - the tiff_open routine calls gdev_prn_allocate_memory which resets the device methods, we need to put them back to be correct for our - device(s), which is done at the end of the tiff_open code: -</p> -<br /> -<code>if (update_procs) { -<dd> if (pdev->ObjectHandlerPushed) {<br /> - gx_copy_device_procs(&pdev->parent->procs, &pdev->procs, (gx_device_procs *)&gs_obj_filter_device.procs);<br /> - pdev = pdev->parent;<br /> - }<br /> - if (pdev->PageHandlerPushed) {<br /> - gx_copy_device_procs(&pdev->parent->procs, &pdev->procs, (gx_device_procs *)&gs_flp_device.procs);<br /> - pdev = pdev->parent;<br /> - }<br /> - /* set tfdev to the bottom device in the chain */<br /> - tfdev = (gx_device_tiff *)pdev;<br /> - while (tfdev->child)<br /> - tfdev = (gx_device_tiff *)tfdev->child;<br /> - if (tfdev->BlackTextHandlerPushed)<br /> - gx_copy_device_procs(&pdev->parent->procs, &pdev->procs, (gx_device_procs *)&gs_black_text_device.procs);<br /> - }<br /> -</dd> -</code><p> -In essence this simply works backwards through the chain of devices, restoring the correct methods as it goes. Note that because the - BlackTextHandlerPushed variable isn't defined in the basic device structure, we have to cast the device pointer to a gx_device_tiff * - so that we can set and check the variable which is defined there. -</p> -<p> -That completes the changes we need to make to the TIFF device to add support for our new code. Now we need to create the black_text device which will do the actual work. -</p> -<p>We don't need any extras in the device structure, so we'll just define our subclassing device as being a gx_device:</p> -<code>/* Black Text device */<br /> -typedef struct gx_device_s gx_device_black_text;<br /> -</code> -<p> -We also don't need any extra storage, but we do need to carry round the basic storage required by a subclassing device, so we do need to define a structure for that: -</p> -<code>typedef struct { -<dd> subclass_common; -</dd>} black_text_subclass_data; -</code> -<p> -Now, we are going to deal with text (obviously) and text, like images, is handled rather awkwardly in the current device interface. - Instead of the interpreter calling the various device methods, the 'text_begin' method creates a text enumerator which it returns - to the interpreter. The text enumerator contains its own set of methods for dealing with text, and the interpreter calls these, - thus bypassing the device itself. Since our subclassing requires us to pass down a chain of devices, when dealing with text and - images we must also implement a chain of enumerators. For subclassing devices which don't process text or images this is catered - for in the default_subclass_* methods, but in this case we need to handle the situation. -</p> -<p>We start by creating our own text enumerator structure: -</p> -<code> -typedef struct black_text_text_enum_s { -<dd> gs_text_enum_common;<br /> - gs_text_enum_t *child; -</dd>} black_text_text_enum_t; -</code> -<p>Here we have a structure which contains the elements common to all enumerators, and a pointer to the next enumerator in the chain, we'll fill that in later.</p> -<p>Ghostscript uses several memory managers, but for PostScript and PDF objects we use a garbage collector. Because we may want to - store pointers to garbage collected objects in the text enumerator, and our device, we need to make the garbage collector aware of - them. This is because the garbage collector can relocate objects in memory, in order to do so safely it needs to update any pointers - referencing those objects with the new location and so it needs to be told about those pointers.</p> -<p>So, we define a garbage collector structure for the text enumerator:</p> -<code>extern_st(st_gs_text_enum);<br /> - gs_private_st_suffix_add1(st_black_text_text_enum, black_text_text_enum_t, - "black_text_text_enum_t", black_text_text_enum_enum_ptrs, black_text_text_enum_reloc_ptrs, - st_gs_text_enum, child); -</code> -<p>The macro 'extern_st' simply defines the structure (st_gs_text_enum) as being of type gs_memory_struct_type_t. We need this structure for the 'superstructure' defined below.</p> -<p>The next macro 'gs_private_st_suffix_add1' is one of a family of macros used to define structures for the garbage collector. These - all end up defining the named structure as being of type 'gc_struct_data_t' and fill in various members of that structure. In this case - we are declaring that the structure: -<dd>Has one pointer to additional garbage collected objects (add_1)</dd> -<dd>Its name is 'st_black_text_text_enum'</dd> -<dd>It is of type 'black_text_text_enum_t'</dd> -<dd>Has the readable name for error messages 'black_text_text_enum_t</dd> -<dd>The routine to be called to enumerate the garbage collected pointers in the structure is 'black_text_text_enum_enum_ptrs'</dd> -<dd>The routine to be called when relocating garbage collcted objects pointed to by ths structure is 'black_text_text_enum_reloc_ptrs</dd> -<dd>The 'superstructure' (ie the structure type this is based on) is 'st_gs_text_enum'. Ths means that all the enumeration and relocation methods for any pointers in the 'common' text enumerator structure get handled by this structure.</dd> -<dd>The one additional pointer to a garbage collected object is the 'child' member.</dd> -<br />The macro takes care of creating all the code we need to deal with this object, essentially it will create 'black_text_text_enum_enum_ptrs' and 'black_text_text_enum_reloc_ptrs' for us. -</p> -<p> -So now we have to do a similar job for the actual device itself. We start by defining the enumeration and relocation routines - for the structure. There are extensive macros for doing this, and we make use of some of them here. Explaining these is out of - the scope of this document, but they are defined and easy to locate in the Ghostscript source tree. -</p> -<code> -static<br /> -ENUM_PTRS_WITH(black_text_enum_ptrs, gx_device *dev);<br /> -return 0; /* default case */<br /> -case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent));<br /> -case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child));<br /> -ENUM_PTRS_END<br /> -<br /> -static RELOC_PTRS_WITH(black_text_reloc_ptrs, gx_device *dev)<br /> -{ -<dd> dev->parent = gx_device_reloc_ptr(dev->parent, gcst);<br /> - dev->child = gx_device_reloc_ptr(dev->child, gcst); -</dd>}RELOC_PTRS_END -</code> -<p>Essentially these simply tell the garbage collector that we are maintaining two pointers to garbage collected objects, the - parent and child devices. Now we use those in the garbage collector 'structure descriptor' for the device. Note this is not - the actual device structure, its the structure used by the garbage collector when dealing with the device. -</p> -<code> -gs_public_st_complex_only(st_black_text_device, gx_device, "black_text", - 0, black_text_enum_ptrs, black_text_reloc_ptrs, gx_device_finalize); -</code> -<p> -Again 'gs_public_st_complex_only' is a macro, and its one of a family, these end up defining structures of type 'gs_memory_struct_t'. -In this case we are declaring: -<dd>The structure type is named 'st_black_text_device'</dd> -<dd>The structure is of size 'gx_device' (ths only works because we don;t need any other storage, otherwise we would have to define the device structure and pass that here).</dd> -<dd>The human readable name for error messages is 'black_text'</dd> -<dd>We don't define a 'clear' routine.</dd> -<dd>The enumerator for GC objects is called 'black_text_enum_ptrs'</dd> -<dd>The relocator for GC objects is called 'black_text_reloc_ptrs'</dd> -<dd>We use the regular 'gx_device_finalize' routine when freeing the object, we don't declare a special one of our own.</dd><br /> -Now we've got all the garbage collector machinery out of the way we can deal with the actual device itself. Because we're only interested in - text, there's only one device method we want to handle, the text_begin method, so we start by prototyping that: -</p> -<code> -/* Device procedures */<br /> -static dev_proc_text_begin(black_text_text_begin); -</code> -<p>Then we define the procedure to initialize the device procs: -</p> -<code> -void black_text_init_dev_procs(gx_device *dev)<br /> -{<br /> - default_subclass_initialize_device_procs(dev);<br /> -<br /> - set_dev_proc(dev, text_begin, black_text_text_begin);<br /> -} -</code> -<p>Then we define the actual device: -</p> -<code> -const -gx_device_black_text gs_black_text_device =<br /> -{<br /> - std_device_dci_type_body(gx_device_black_text, 0, "black_text", &st_black_text_device,<br /> - MAX_COORD, MAX_COORD,<br /> - MAX_RESOLUTION, MAX_RESOLUTION,<br /> - 1, 8, 255, 0, 256, 1),<br /> - black_text_initialize_device_procs<br /> -}; -</code> -<p>The call to default_subclass_initialize_device_procs assigns the -default methods for a subclassing device. We then override the -text_begin method to our specific one. The main body of the macro is:</p> -<code> -const -gx_device_black_text gs_black_text_device =<br /> -{<br /> - std_device_dci_type_body(gx_device_black_text, 0, "black_text", &st_black_text_device,<br /> - MAX_COORD, MAX_COORD,<br /> - MAX_RESOLUTION, MAX_RESOLUTION,<br /> - 1, 8, 255, 0, 256, 1), -</code> -<p>This simply defines an instance of the 'gx_device_black_text' structure (which is simply a gx_device_s structure) initialised - using a macro (yet another family of macros). Here we use the 'st_black_text_device' structure descriptor we created above, - and some dummy values for the resolution, colour depth etc. Since this device doesn't do rendering these values aren't useful - and these defaults should be fine. -</p> -<p>Now, for text we need to fill in all the procedures in the text enumerator, we'll start by defining the 'resync' method, and - then use this as a template for most of the other methods in the text enumerator: -</p> -<code> -static int -black_text_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom) -{ -<dd> black_text_text_enum_t *penum;<br /> - gs_text_enum_t * child = penum->child;<br /> - int code;<br /> -<br /> - code = child->procs->resync(child, pfrom);<br /> - gs_text_enum_copy_dynamic(pte, child, true);<br /> - return code;<br /> -</dd>} -</code> -<p>The routine starts by casting the generic text enumerator to our specific type of text enumerator. From that we can get the child - enumerator, and we simply pass the operation on directly to the child (remembering to pass the child enumerator as an argument, not our own one!). -</p> -<p> -Now, on return it may be that the child has modified the contents of the enumerator, so we must copy anything that might have changed - from the child enumerator to our own. That's what the 'gs_text_enum_copy_dynamic' routine does. After that we simply return the saved return value. -</p> -<p> -All the other routines are basically the same as this, we don't really want to do anything in the text enumeration so we just hand off the processing to the child. -</p> -<code> -static int -black_text_text_process(gs_text_enum_t *pte) -{ -<dd> black_text_text_enum_t *penum = (black_text_text_enum_t *)pte;<br /> - gs_text_enum_t * child = penum->child;<br /> - int code;<br /> -<br /> - code = child->procs->process(child);<br /> - gs_text_enum_copy_dynamic(pte, child, true);<br /> - return code;<br /> -</dd>}<br /> -static bool -black_text_text_is_width_only(const gs_text_enum_t *pte) -{ -<dd> black_text_text_enum_t *penum = (black_text_text_enum_t *)pte;<br /> - gs_text_enum_t * child = penum->child;<br /> - int code;<br /> -<br /> - code = child->procs->is_width_only(child);<br /> - gs_text_enum_copy_dynamic((gs_text_enum_t *)pte, child, true);<br /> - return code;<br /> -</dd>}<br /> -static int -black_text_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth) -{ -<dd> black_text_text_enum_t *penum = (black_text_text_enum_t *)pte;<br /> - gs_text_enum_t * child = penum->child;<br /> - int code;<br /> -<br /> - code = child->procs->current_width(child, pwidth);<br /> - gs_text_enum_copy_dynamic((gs_text_enum_t *)pte, child, true);<br /> - return code;<br /> -</dd>}<br /> -static int -black_text_text_set_cache(gs_text_enum_t *pte, const double *pw, - gs_text_cache_control_t control) -{ -<dd> black_text_text_enum_t *penum = (black_text_text_enum_t *)pte;<br /> - gs_text_enum_t * child = penum->child;<br /> - int code;<br /> -<br /> - code = child->procs->set_cache(child, pw, control);<br /> - gs_text_enum_copy_dynamic(pte, child, true);<br /> - return code;<br /> -</dd>}<br /> -static int -black_text_text_retry(gs_text_enum_t *pte) -{ -<dd> black_text_text_enum_t *penum = (black_text_text_enum_t *)pte;<br /> - gs_text_enum_t * child = penum->child;<br /> - int code;<br /> -<br /> - code = child->procs->retry(child);<br /> - gs_text_enum_copy_dynamic(pte, child, true);<br /> - return code;<br /> -</dd>}<br /> -static void -black_text_text_release(gs_text_enum_t *pte, client_name_t cname) -{ -<dd> black_text_text_enum_t *penum = (black_text_text_enum_t *)pte;<br /> - gs_text_enum_t * child = penum->child;<br /> -<br /> - child->procs->release(child, cname);<br /> - gx_default_text_release(pte, cname);<br /> -</dd>} -</code> -<p>The 'release' method is very slightly different, because we need to free the numerator, so we call 'gx_default_text_release'</p> -<p>Now, finally, we can define the 'text_begin' device method, the first thing we do is a convenience, we define a - 'gs_text_enum_procs' instance which is initialised to point to all the text enumerator methods we defined above: -</p> -<code> -static const gs_text_enum_procs_t black_text_text_procs = { -<dd> black_text_text_resync, black_text_text_process, - black_text_text_is_width_only, black_text_text_current_width, - black_text_text_set_cache, black_text_text_retry, - black_text_text_release -</dd>};</code> -<p>So on to the text_begin method: -</p> -<code> -/* The device method which we do actually need to define. - */<br /> -int black_text_text_begin(gx_device *dev, gs_imager_state *pis, const gs_text_params_t *text,<br /> - gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath,<br /> - gs_memory_t *memory, gs_text_enum_t **ppte)<br /> -{<br /> -<dd> black_text_text_enum_t *penum;<br /> - int code;<br /> - gs_text_enum_t *p;<br /> -<br /> - rc_alloc_struct_1(penum, black_text_text_enum_t, &st_black_text_text_enum, memory,<br /> - return_error(gs_error_VMerror), "black_text_text_begin");<br /> - penum->rc.free = rc_free_text_enum;<br /> - code = gs_text_enum_init((gs_text_enum_t *)penum, &black_text_text_procs,<br /> - dev, pis, text, font, path, pdcolor, pcpath, memory);<br /> - if (code < 0) {<br /> - gs_free_object(memory, penum, "black_text_text_begin");<br /> - return code;<br /> - }<br /> - *ppte = (gs_text_enum_t *)penum;<br /> -<br /> - code = default_subclass_text_begin(dev, pis, text, font, path, pdcolor, pcpath, memory, &p);<br /> - if (code < 0) {<br /> - gs_free_object(memory, penum, "black_text_text_begin");<br /> - return code;<br /> - }<br /> - penum->child = p;<br /> -<br /> - return 0;<br /> -</dd>} -</code> -<p>This uses library macros to create and initialise the text enumerator. Text enumerators are reference counted - (and garbage collected.....) so we use the rc_alloc_struct family of macros, the '1' is the initial reference - count that we want to have. We then call 'gs_text_enum_init' to initialise the newly created structure, passing - in the text procs we just created as one of the arguments. -</p> -<p>We then set the returned enumerator to point to the newly created text enumerator. Finally we pass the 'text_begin' - method on to the child device using the 'default_subclass_text_begin' method and we store the returned text enumerator - in the child pointer of our own enumerator. -</p> -<p>At this point the code should compile and run properly, but it won;t actually do anything yet. For that we need to - modify the current colour before we run the text. Fortunately we don't need to deal with the graphics state, the text_begin - method is given the colour index to be used so all we need to do is alter that. We do, however, have to cater for what the - device thinks 'black' actually is, but there are graphics library calls to deal with both finding that information and - setting a colour index from it: -</p> -<code> -int black_text_text_begin(gx_device *dev, gs_imager_state *pis, const gs_text_params_t *text,<br /> - gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath,<br /> - gs_memory_t *memory, gs_text_enum_t **ppte)<br /> -{ -<dd> black_text_text_enum_t *penum;<br /> - int code;<br /> - gs_text_enum_t *p;<br /> -<br /> - /* Set the colour index in 'pdcolor' to be whatever the device thinks black shoudl be */<br /> - set_nonclient_dev_color((gx_device_color *)pdcolor, gx_device_black((gx_device *)dev));<br /> -</dd> -</code> -<p>That concludes the worked example and the documentation on device subclassing. -</p> -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2013-2022 Artifex Software, Inc. All rights -reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, -modified or distributed except as expressly authorized under the terms -of the license contained in the file LICENSE in this distribution. - -For more information about licensing, please visit -http://www.artifex.com/licensing/ -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> diff --git a/doc/thirdparty.htm b/doc/thirdparty.htm deleted file mode 100644 index 8d3f8634..00000000 --- a/doc/thirdparty.htm +++ /dev/null @@ -1,215 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width"> - <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i" rel="stylesheet"> - <link rel="shortcut icon" href="images/favicon.svg"> - <title>Third Party Libraries Used by Ghostscript and GhostPDL</title> - <link href="default.css" rel="stylesheet" type="text/css"> -</head> - -<body> - <header><div class="title"><a href="index.html"><h1 aria-label="title">Ghostscript documentation</h1><h2 aria-label="version"></h2></a></div><a href="Search.htm" aria-label="Search" id="searchSite"><div class="search"></div></a></header> - <main> - <article> - <div class="outer"> - - <div class="inner"> -<!--START EDITING HERE--> - -<h1>Third Party Libraries Used by Ghostscript and GhostPDL</h1> - -<p> -The table below details the third party libraries that Ghostscript and/or -GhostPDL include, the versions QA tested and shipped with our releases, -the relevant license, and the "upstream" URL. -<p> - -<table> -<tr height="60"> -<th align="center">Library Name</th> -<th align="center">Version</th> -<th align="center">Function</th> -<th align="center">License</th> -<th align="center">URL</th> -</tr> - -<tr height="60"> -<td align="center">CUPS<br> -<font size="1">(AGPL Release Only)</font></td> -<td align="center">2.8.0</td> -<td align="center">CUPS raster format output</td> -<td align="center">GPL Version 3</td> -<td align="center"><a href="http://www.cups.org">http://www.cups.org/</a></td> -</tr> - -<tr height="60"> -<td align="center">eXpat</td> -<td align="center">2.4.1</td> -<td align="center">XML parsing for XPS interpreter</td> -<td align="center">MIT/eXpat License</td> -<td align="center"><a href="http://expat.sourceforge.net/">http://expat.sourceforge.net/</a></td> -</tr> - -<tr height="60"> -<td align="center">FreeType</td> -<td align="center">2.11.1</td> -<td align="center">Font scaling and rendering for Ghostscript</td> -<td align="center">FreeType License<br> -<font size="1">(BSD-style license with a credit clause)</font></td> -<td align="center"><a href="http://www.freetype.org/">http://www.freetype.org/</a></td> -</tr> - -<tr height="60"> -<td align="center">jbig2dec</td> -<td align="center">0.19</td> -<td align="center">JBIG2 decoding for the PDF interpreter</td> -<td align="center">Licensed with Ghostscript/GhostPDL<br> -<font size="1">(copyright owned by Artifex)</font></td> -<td align="center"><a href="http://www.ghostscript.com/">http://www.ghostscript.com/</a></td> -</tr> - -<tr height="60"> -<td align="center">libjpeg</td> -<td align="center">9d<br> -<font size="1">with patches</font></td> -<td align="center">JPEG/DCT decoding/encoding</td> -<td align="center">"Free"<br> -<font size="1">Can be used in commercial applications without royalty, with acknowledgement.</font></td> -<td align="center"><a href="http://www.ijg.org/">http://www.ijg.org/</a></td> -</tr> - -<tr height="60"> -<td align="center">LittleCMS 2 mt<br> -<font size="1">(lcms2mt - thread save fork of lcms2)</font></td> -<td align="center">2.10mt</td> -<td align="center">ICC profile based color conversion and management</td> -<td align="center">MIT LICENSE</td> -<td align="center"><a href="http://www.ghostscript.com/">http://www.ghostscript.com/</a></td> -</tr> - -<tr height="60"> -<td align="center">libpng</td> -<td align="center">1.6.37</td> -<td align="center">PNG image encoding/decoding.</td> -<td align="center">libpng license<br> -<font size="1">classified as "a permissive free software license"</font></td> -<td align="center"><a href="http://www.libpng.org/">http://www.libpng.org/</a></td> -</tr> - -<tr height="60"> -<td align="center">OpenJPEG</td> -<td align="center">2.4.0</td> -<td align="center">JPEG2000 image decoding for the PDF interpreter</td> -<td align="center">BSD-style</td> -<td align="center"><a href="http://www.openjpeg.org/">http://www.openjpeg.org/</a></td> -</tr> - -<tr height="60"> -<td align="center">libtiff</td> -<td align="center">4.2.0</td> -<td align="center">TIFF image encoding/decoding</td> -<td align="center">BSD-style</td> -<td align="center"><a href="http://www.remotesensing.org/libtiff/">http://www.remotesensing.org/libtiff/</a></td> -</tr> - -<tr height="60"> -<td align="center">zlib</td> -<td align="center">1.2.11</td> -<td align="center">(De)Flate compression</td> -<td align="center">zlib License<br> -<font size="1">classified as "a permissive free software license"</font></td> -<td align="center"><a href="http://www.zlib.net/">http://www.zlib.net/</a></td> -</tr> - -<tr> - -<td colspan="5" align="left"><hr>The following are optional.<hr></td> -</tr> - -<tr height="60"> -<td align="center">tesseract</td> -<td align="center">4.1.0<br> -<font size="1">with patches</font></td> -<td align="center">Optical Character Recognition (OCR) library</td> -<td align="center">Apache License 2.0<br> -<font size="1"></font></td> -<td align="center"><a href="https://github.com/tesseract-ocr/tesseract">https://github.com/tesseract-ocr/tesseract</a></td> -</tr> - -<tr height="60"> -<td align="center">leptonica</td> -<td align="center">1.80.0<br> -<font size="1">with patches</font></td> -<td align="center">Image processing toolkit - support library for tesseract OCR</td> -<td align="center">Leptonica License<br> -<font size="1">"a permissive free software license"</font></td> -<td align="center"><a href="http://www.leptonica.org/">http://www.leptonica.org/</a></td> -</tr> - -<tr> - -<td colspan="5" align="left"><hr>The following are no-cost, open source licensed, but not GPL compatible.<hr></td> -</tr> - -<tr height="60"> -<td align="center">jpegxr<br> -<font size="1">(JPEG XR reference software)</font></td> -<td align="center">1.8</td> -<td align="center">HDPhoto/JPEG-XR image decoding for the XPS interpreter</td> -<td align="center">ITU/ISO/IEC "Free" License<br> -<font size="1">Reference implementation</font></td> -<td align="center"><a href="http://www.itu.int/rec/T-REC-T.835">http://www.itu.int/rec/T-REC-T.835</a></td> -</tr> - -<tr> -<td colspan="5" align="left"><hr>The following are relevant to Artifex Software commercial releases only.<hr></td> -</tr> - -<tr height="60"> -<td align="center">AGFA UFST<br> -<font size="1">Optional</font></td> -<td align="center">5.x/6.x<br> -<font size="1">with patches</font></td> -<td align="center">Access, scale and render AGFA MicroType fonts</td> -<td align="center">Commercial</td> -<td align="center"><a href="http://www.monotypeimaging.com/">http://www.monotypeimaging.com/</a></td> -</tr> - -</table> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 2005-2022 Artifex Software, Inc. -All rights reserved.</small> - -<p> -This software is provided AS-IS with no warranty, either express or -implied. - -This software is distributed under license and may not be copied, modified -or distributed except as expressly authorized under the terms of that -license. Refer to licensing information at <a href="https://www.artifex.com">https://www.artifex.com</a> -or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, -Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. - -<p> -<small>Ghostscript version 9.56.1, 4 April 2022 - -<!-- [3.0 end visible trailer] ============================================= --> - - - -<!--FINISH EDITING HERE--> - </div><!-- close inner --> - </div><!-- close outer --> - </article> - </main> - <script src="site.js"></script> -</body> -</html> |