diff options
Diffstat (limited to 'Master/xemtex/doc/ghostscript/Drivers.htm')
-rw-r--r-- | Master/xemtex/doc/ghostscript/Drivers.htm | 2538 |
1 files changed, 0 insertions, 2538 deletions
diff --git a/Master/xemtex/doc/ghostscript/Drivers.htm b/Master/xemtex/doc/ghostscript/Drivers.htm deleted file mode 100644 index c97bfaeb642..00000000000 --- a/Master/xemtex/doc/ghostscript/Drivers.htm +++ /dev/null @@ -1,2538 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> -<title>The interface between Ghostscript and device drivers</title> -<!-- $Id: Drivers.htm,v 1.21.2.11.2.5 2003/05/17 14:38:59 giles Exp $ --> -<!-- Originally: drivers.txt --> -<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style"> -</head> - -<body> -<!-- [1.0 begin visible header] ============================================ --> - -<!-- [1.1 begin headline] ================================================== --> - -<h1>The interface between Ghostscript and device drivers</h1> - -<!-- [1.1 end headline] ==================================================== --> - -<!-- [1.2 begin table of contents] ========================================= --> - -<h2>Table of contents</h2> - -<blockquote><ul> -<li><a href="#Adding_drivers">Adding a driver</a> -<li><a href="#KISS">Keeping things simple</a> -<li><a href="#Structure">Driver structure</a> -<ul> -<li><a href="#Structure_definition">Structure definition</a> -<li><a href="#Sophisticated">For sophisticated developers only</a> -</ul> -<li><a href="#coordinates_and_types">Coordinates and types</a> -<ul> -<li><a href="#Coordinate_system">Coordinate system</a> -<li><a href="#Color_definition">Color definition</a> -<li><a href="#Types">Types</a> -</ul> -<li><a href="#Coding_conventions">Coding conventions</a> -<ul> -<li><a href="#Allocating_storage">Allocating storage</a> -<li><a href="#Driver_instance_allocation">Driver instance allocation</a> -</ul> -<li><a href="#Printer_drivers">Printer drivers</a> -<li><a href="#Driver_procedures">Driver procedures</a> -<ul> -<li><a href="#Life_cycle">Life cycle</a> -<li><a href="#Open_close">Open, close, sync, copy</a> -<li><a href="#Color_mapping">Color and alpha mapping</a> -<li><a href="#Pixel_level_drawing">Pixel-level drawing</a> -<ul> -<li><a href="#Bitmap_imaging">Bitmap imaging</a> -<li><a href="#Pixmap_imaging">Pixmap imaging</a> -<li><a href="#Compositing">Compositing</a> - [<a href="#S_spec">S</a>, <a href="#T_spec">T</a>, <a href="#F_spec">f</a>, - <a href="#Compositing_notes">Notes</a>] -</ul> -<li><a href="#Polygon_level_drawing">Polygon-level drawing</a> -<li><a href="#High_level_drawing">High-level drawing</a> -<ul> -<li><a href="#Paths">Paths</a> -<li><a href="#Images">Images</a> [<a href="#Images_notes">Notes</a>] -<li><a href="#Text">Text</a> [<a href="#Text_notes">Notes</a>] -</ul> -<li><a href="#Reading_bits_back">Reading bits back</a> -<li><a href="#Parameters">Parameters</a> -<ul> -<li><a href="#Default_CRD_parameters">Default color rendering dictionary (CRD) parameters</a> -</ul> -<li><a href="#External_fonts">External fonts</a> -<li><a href="#Page_devices">Page devices</a> -<li><a href="#Miscellaneous">Miscellaneous</a> -</ul> -</ul></blockquote> - -<!-- [1.2 end table of contents] =========================================== --> - -<!-- [1.3 begin hint] ====================================================== --> - -<p>For other information, see the <a href="Readme.htm">Ghostscript -overview</a> and the documentation 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="Adding_drivers"></a>Adding a driver</h2> - -<p> -To add a driver to Ghostscript, first pick a name for your device, say -"<b><tt>smurf</tt></b>". (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 <b><tt>contrib.mak</tt></b> in two places. - -<ol> -<li>The list of devices, in the section headed "Catalog". Add -<b><tt>smurf</tt></b> to the list. - -<li>The section headed "Device drivers". - -<p> -Suppose the files containing the smurf driver are called -"<b><tt>joe</tt></b>" and "<b><tt>fred</tt></b>". Then you should add the -following lines: - -<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 <b><tt>joe.c</tt></b> and <b><tt>fred.c</tt></b> depend on. -If the smurf driver also needs special libraries, for instance a library -named "<b><tt>gorf</tt></b>", then the entry should look like this: - -<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: - -<blockquote> -<pre>$(DD)smurf.dev : $(smurf_) $(GLD)page.dev - $(SETPDEV) $(DD)smurf $(smurf_)</pre> -</blockquote> - -<p> -or - -<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, -</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="../src/gdevepsn.c">gdevepsn.c</a> and <a -href="../src/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="../src/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="../src/gdevcdj.c">gdevcdj.c</a> and <a -href="../src/gdevstc.c">gdevstc.c</a>, are far too complex to read. - -<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> -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="../src/gdevepsn.c">gdevepsn.c</a> and <a -href="../src/gdevdjet.c">gdevdjet.c</a> are good examples of this approach. - -<hr> - -<h2><a name="Structure"></a>Driver structure</h2> - -<p> -A device is represented by a structure divided into three parts: - -<ul> -<li>procedures that are (normally) shared by all instances of each device; - -<li>parameters that are present in all devices but may be different for -each device or instance; and - -<li>device-specific parameters that may be different for each instance. -</ul> - -<p> -Normally the procedure structure is defined and initialized at compile -time. 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. Both of -these structures should be declared as <b><tt>const</tt></b>, but for backward -compatibility reasons the latter is not. - -<p> -The <b><tt>gx_device_common</tt></b> 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="../src/gxdevice.h">gxdevice.h</a> or, if applicable, <a -href="../src/gdevprn.h">gdevprn.h</a>. - -<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>... procedures ...</em></b> }, /* std_procs */ - <b><em>... device-specific parameter values if any ...</em></b> -};</pre> -</blockquote> - -<p> -The device structure instance <b>must</b> have the name -<b><tt>gs_smurf_device</tt></b>, where <b><tt>smurf</tt></b> is the device -name used in <b><tt>contrib.mak</tt></b>. <b><tt>gx_device_common</tt></b> -is a macro consisting only of the element definitions. - -<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 <b><tt>gx_device *</tt></b> as -their first argument, and must cast it to -<b><tt>smurf_device *</tt></b> internally. For example, in the code -for the "memory" device, the first argument to all routines is called -<b><tt>dev</tt></b>, but the routines actually use <b><tt>mdev</tt></b> to -refer to elements of the full structure, using the following standard -initialization statement at the beginning of each procedure: - -<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.) - -<h3><a name="Structure_definition"></a>Structure definition</h3> - -<p> -You should consult the definition of struct <b><tt>gx_device_s</tt></b> in -<a href="../src/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: - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=top> <td><b><tt>const char *dname;</tt></b> - <td> - <td>The device name -<tr valign=top> <td><b><tt>bool is_open;</tt></b> - <td> - <td>True if device has been opened -<tr valign=top> <td><b><tt>gx_device_color_info color_info;</tt></b> - <td> - <td>Color information -<tr valign=top> <td><b><tt>int width;</tt></b> - <td> - <td>Width in pixels -<tr valign=top> <td><b><tt>int height;</tt></b> - <td> - <td>Height in pixels -</table></blockquote> - -<p> -The name in the structure (<b><tt>dname</tt></b>) should be the same as the -name in <a href="../src/contrib.mak">contrib.mak</a>. - -<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: - -<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>The definition of <b><tt>gx_device_common</tt></b> and the procedures - in <a href="../src/gxdevcli.h">gxdevcli.h</a>. -<li>Possibly, the default forwarding procedures declared in - <a href="../src/gxdevice.h">gxdevice.h</a> and implemented in - <a href="../src/gdevnfwd.c">gdevnfwd.c</a>. -<li>The device procedure record completion routines in - <a href="../src/gdevdflt.c">gdevdflt.c</a>. -<li>Possibly, the default device implementation in - <a href="../src/gdevdflt.c">gdevdflt.c</a>, - <a href="../src/gdevddrw.c">gdevddrw.c</a>, and - <a href="../src/gxcmap.c">gxcmap.c</a>. -<li>The bounding box device in <a href="../src/gdevbbox.c">gdevbbox.c</a> - (probably just adding <b><tt>NULL</tt></b> procedure entries if the - new procedures don't produce output). -<li>These devices that must have complete (non-defaulted) procedure vectors: -<ul> -<li>The null device in <a href="../src/gdevnfwd.c">gdevnfwd.c</a>. -<li>The command list "device" in <a href="../src/gxclist.c">gxclist.c</a>. - This is not an actual device; it only defines procedures. -<li>The "memory" devices in <a href="../src/gdevmem.h">gdevmem.h</a> and - <b><tt>gdevm*.c</tt></b>. -<li>The halftoning device in <a href="../src/gdevht.c">gdevht.c</a>. -</ul> -<li>The clip list accumulation "device" in - <a href="../src/gxacpath.c">gxacpath.c</a>. -<li>The clipping "devices" <a href="../src/gxclip.c">gxclip.c</a>, - <a href="../src/gxclip2.c">gxclip2.c</a>, - and <a href="../src/gxclipm.c">gxclipm.c</a>. -<li>The pattern accumulation "device" in - <a href="../src/gxpcmap.c">gxpcmap.c</a>. -<li>The hit detection "device" in <a href="../src/gdevhit.c">gdevhit.c</a>. -<li>The generic printer device macros in - <a href="../src/gdevprn.h">gdevprn.h</a>. -<li>The generic printer device code in - <a href="../src/gdevprn.c">gdevprn.c</a>. -<li>The RasterOp source device in - <a href="../src/gdevrops.c">gdevrops.c</a>. -</ul></blockquote> - -<p> -You may also have to change the code for -<b><tt>gx_default_get_params</tt></b> or -<b><tt>gx_default_put_params</tt></b> in <a -href="../src/gsdparam.c">gsdparam.c</a>. - -<p> -You should not have to change any of the real devices in the standard -Ghostscript distribution (listed in <a href="../src/devs.mak">devs.mak</a> -and <a href="../src/contrib.mak">contrib.mak</a>) or any of your own -devices, because all of them are supposed to use the macros in <a -href="../src/gxdevice.h">gxdevice.h</a> or <a -href="../src/gdevprn.h">gdevprn.h</a> to define and initialize their state. - -<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 -<b><tt>int</tt></b>. (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> -Drivers must check (and, if necessary, clip) the coordinate parameters given -to them: they should not assume the coordinates will be in bounds. The -<b><tt>fit_fill</tt></b> and <b><tt>fit_copy</tt></b> macros in <a -href="../src/gxdevice.h">gxdevice.h</a> are very helpful in doing this. - -<h3><a name="Color_definition"></a>Color definition</h3> - -<p> -Ghostscript represents colors internally as RGB or CMYK values. In -communicating with devices, however, it assumes that each device has a -palette of colors identified by integers (to be precise, elements of type -<b><tt>gx_color_index</tt></b>). Drivers may provide a uniformly spaced -gray ramp or color cube for halftoning, or they may do their own color -approximation, or both. - -<p> -The <b><tt>color_info</tt></b> member of the device structure defines the -color and gray-scale capabilities of the device. Its type is defined as -follows: - -<blockquote> -<pre>typedef struct gx_device_color_info_s { - int num_components; /* 1 = gray only, 3 = RGB, */ - /* 4 = CMYK */ - int depth; /* # of bits per pixel */ - gx_color_value max_gray; /* # of distinct gray levels -1 */ - gx_color_value max_rgb; /* # of distinct color levels -1 */ - /* (only relevant if num_comp. > 1) */ - gx_color_value dither_gray; /* size of gray ramp for halftoning */ - gx_color_value dither_rgb; /* size of color cube ditto */ - /* (only relevant if num_comp. > 1) */ -} gx_device_color_info;</pre> -</blockquote> - -<p> -The following macros (in <a href="../src/gxdevice.h">gxdevice.h</a>) provide -convenient shorthands for initializing this structure for ordinary -black-and-white or color devices: - -<blockquote> -<b><tt>#define dci_black_and_white</tt></b> ...<br> -<b><tt>#define dci_color(depth,maxv,dither)</tt></b> ... -</blockquote> - -<p> -The idea is that a device has a certain number of gray levels -(<b><tt>max_gray</tt></b>+1) and a certain number of colors -(<b><tt>max_rgb</tt></b>+1) that it can produce directly. When Ghostscript -wants to render a given RGB or CMYK color as a device color, it first tests -whether the color is a gray level (if <b><tt>num_components</tt></b> is 1, -it converts all colors to gray levels), and if so: - -<blockquote> -If <b><tt>max_gray</tt></b> is large (>= 31), Ghostscript asks the -device to approximate the gray level directly. If the device returns a -valid <b><tt>gx_color_index</tt></b>, Ghostscript uses it. Otherwise, -Ghostscript assumes that the device can represent -<b><tt>dither_gray</tt></b> 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: - -<blockquote> -If <b><tt>max_rgb</tt></b> is large (>= 31), Ghostscript asks the device -to approximate the color directly. If the device returns a valid -<b><tt>gx_color_index</tt></b>, Ghostscript uses it. Otherwise, -Ghostscript assumes that the device can represent - -<blockquote> -<b><tt>dither_rgb</tt></b> × <b><tt>dither_rgb</tt></b> × <b><tt>dither_rgb</tt></b> -</blockquote> - -<p> -distinct colors, equally spaced throughout the color cube, and uses two of -the nearest ones to the desired color for halftoning. -</blockquote> - -<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. - -<dl> -<dt><b><tt>gx_color_value</tt></b> (defined in <b><tt>gxdevice.h</tt></b>) -<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: -<b><tt>gx_color_value_bits</tt></b> is the number of bits actually used, -and <b><tt>gx_max_color_value</tt></b> is the maximum value, equal to -(2^<small><sup><b><tt>gx_max_color_value_bits</tt></b></sup></small>)-1. -</dl> - -<dl> -<dt><b><tt>gx_device</tt></b> (defined in <b><tt>gxdevice.h</tt></b>) -<dd>This is the device structure, as explained above. -</dl> - -<dl> -<dt><b><tt>gs_matrix</tt></b> (defined in <b><tt>gsmatrix.h</tt></b>) -<dd>This is a 2-D homogeneous coordinate transformation matrix, used by -many Ghostscript operators. -</dl> - -<dl> -<dt><b><tt>gx_color_index</tt></b> (defined in <b><tt>gxdevice.h</tt></b>) -<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. Ghostscript doesn't ever do -any computations with <b><tt>gx_color_index</tt></b> values: it gets them -from <b><tt>map_rgb_color</tt></b> or <b><tt>map_cmyk_color</tt></b> and -hands them back as arguments to several other procedures. The special -value <b><tt>gx_no_color_index</tt></b> (defined as -<b><tt>(gx_color_index)(-1)</tt></b> ) means "transparent" for some of -the procedures. The type definition is simply: - -<blockquote><b><tt> -typedef unsigned long gx_color_index; -</tt></b></blockquote> -</dl> - -<dl> -<dt><b><tt>gs_param_list</tt></b> (defined in <a -href="../src/gsparam.h">gsparam.h</a>) -<dd>This is a parameter list, which is used to read and set attributes in a -device. See the comments in <a href="../src/gsparam.h">gsparam.h</a>, and -the <a href="#Parameters">description of the <b><tt>get_params</tt></b> and -<b><tt>put_params</tt></b> procedures</a> below, for more detail. -</dl> - -<dl> -<dt><b><tt>gx_tile_bitmap</tt></b> (defined in -<a href="../src/gxbitmap.h">gxbitmap.h</a>) -<br><b><tt>gx_strip_bitmap</tt></b> (defined in -<a href="../src/gxbitmap.h">gxbitmap.h</a>) -<dd>These structure types represent bitmaps to be used as a tile for -filling a region (rectangle). <b><tt>gx_tile_bitmap</tt></b> is an older -type lacking <b><tt>shift</tt></b> and <b><tt>rep_shift</tt></b>; -<b><tt>gx_strip_bitmap</tt></b> has superseded it, and it should not 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). Requirements: - * strip_shift < rep_width - * strip_height % rep_height = 0 - * shift = (strip_shift * (size.y / strip_height)) % rep_width - */ -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 strip_height; - ushort strip_shift; - ushort shift; -} gx_strip_bitmap;</pre> -</blockquote> -</dl> - -<hr> - -<h2><a name="Coding_conventions"></a>Coding conventions</h2> - -<p> -All the driver procedures defined below that return <b><tt>int</tt></b> -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="../src/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: - -<blockquote><dl> -<dt><b><tt>gs_error_invalidfileaccess</tt></b> -<dd>An attempt to open a file failed. - -<dt><b><tt>gs_error_ioerror</tt></b> -<dd>An error occurred in reading or writing a file. - -<dt><b><tt>gs_error_limitcheck</tt></b> -<dd>An otherwise valid parameter value was too large for the -implementation. - -<dt><b><tt>gs_error_rangecheck</tt></b> -<dd>A parameter was outside the valid range. - -<dt><b><tt>gs_error_VMerror</tt></b> -<dd>An attempt to allocate memory failed. (If this happens, the procedure -should release all memory it allocated before it returns.) -</dl></blockquote> - -<p> -If a driver does return an error, rather than a simple return statement it -should use the <b><tt>return_error</tt></b> macro defined in <a -href="../src/gx.h">gx.h</a>, which is automatically included by <a -href="../src/gdevprn.h">gdevprn.h</a> but not by <a -href="../src/gserrors.h">gserrors.h</a>. For example - -<blockquote><b><tt> -return_error(gs_error_VMerror); -</tt></b></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 -<b><tt>malloc</tt></b> to allocate any storage that stays around after the -procedure returns. Instead, they must use <b><tt>gs_malloc</tt></b> and -<b><tt>gs_free</tt></b>, which have slightly different calling conventions. -(The prototypes for these are in <a href="../src/gsmemory.h">gsmemory.h</a>, -which is included in <a href="../src/gx.h">gx.h</a>, which is included in <a -href="../src/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). - -<blockquote> -<pre>char *gs_malloc(uint num_elements, uint element_size, - const char *client_name);</pre> -</blockquote> - -<p> -Like <b><tt>calloc</tt></b>, but unlike <b><tt>malloc</tt></b>, -<b><tt>gs_malloc</tt></b> takes an element count and an element size. For -structures, <b><tt>num_elements</tt></b> is 1 and -<b><tt>element_size</tt></b> is <b><tt>sizeof</tt></b> the structure; for -byte arrays, <b><tt>num_elements</tt></b> is the number of bytes and -<b><tt>element_size</tt></b> is 1. Unlike <b><tt>calloc</tt></b>, -<b><tt>gs_malloc</tt></b> does <b>not</b> clear the block of storage. - -<p> -The <b><tt>client_name</tt></b> is used for tracing and debugging. It must -be a real string, not <b><tt>NULL</tt></b>. Normally it is the name of the -procedure in which the call occurs. - -<blockquote> -<pre>void gs_free(char *data, uint num_elements, uint element_size, - const char *client_name);</pre> -</blockquote> - -<p> -Unlike <b><tt>free</tt></b>, <b><tt>gs_free</tt></b> demands that -<b><tt>num_elements</tt></b> and element_size be supplied. It also -requires a client name, like <b><tt>gs_malloc</tt></b>. - -<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 -<b><tt>gs_copydevice</tt></b> procedure defined in <a -href="../src/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="../src/gsmemory.h">gsmemory.h</a> -and <a href="../src/gsstruct.h">gsstruct.h</a>. - -<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. Of the driver procedures defined in the -next section, they only need implement two: <b><tt>map_rgb_color</tt></b> -(or <b><tt>map_cmyk_color</tt></b>) and <b><tt>map_color_rgb</tt></b>. In -addition, they must implement a <b><tt>print_page</tt></b> or -<b><tt>print_page_copies</tt></b> procedure. There are macros in <a -href="../src/gdevprn.h">gdevprn.h</a> that generate the device structure for -such devices, of which the simplest is <b><tt>prn_device</tt></b>; for an -example, see <a href="../src/gdevbj10.c">gdevbj10.c</a>. If you are writing -a printer driver, we suggest you start by reading <a -href="../src/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> -The <b><tt>print_page</tt></b> procedures are defined as follows: - -<blockquote> -<pre>int (*print_page)(P2(gx_device_printer *, FILE *)) -int (*print_page_copies)(P3(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 <b><tt>print_page</tt></b> procedure must call one of the -following procedures: - -<blockquote> -<pre>int gdev_prn_copy_scan_lines(P4(gx_device_printer *pdev, int y, byte *str, - uint size)</pre> -</blockquote> - -<p> -For this procedure, <b><tt>str</tt></b> is where the data should be copied to, and <b><tt>size</tt></b> is -the size of the buffer starting at <b><tt>str</tt></b>. This procedure returns the number -of scan lines copied, or <0 for an error. <b><tt>str</tt></b> need not be aligned. - -<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, <b><tt>*actual_data</tt></b> is -set to point to it; otherwise, the scan line is copied to the buffer -starting at <b><tt>str</tt></b>, and <b><tt>*actual_data</tt></b> is set to -<b><tt>str</tt></b>. This saves a copying step most of the time. -<b><tt>str</tt></b> need not be aligned; however, if -<b><tt>*actual_data</tt></b> is set to point to an existing scan line, it -will be aligned. (See the description of the <b><tt>get_bits</tt></b> -procedure below for more details.) - -<p> -In either case, each row of the image is stored in the form described in -the comment under <b><tt>gx_tile_bitmap</tt></b> above; each pixel takes -the number of bits specified as <b><tt>color_info.depth</tt></b> in the -device structure, and holds values returned by the device's -<b><tt>map_</tt></b>{<b><tt>rgb</tt></b>,<b><tt>cmyk</tt></b>}<b><tt>_color</tt></b> -procedure. - -<p> -The <b><tt>print_page</tt></b> procedure can determine the number of bytes -required to hold a scan line by calling: - -<blockquote> -<pre>uint gdev_prn_raster(P1(gx_device_printer *))</pre> -</blockquote> - -<p> -For a very simple concrete example, we suggest reading the code in -<b><tt>bit_print_page</tt></b> in <a href="../src/gdevbit.c">gdevbit.c</a>. - -<p> -If the device provides <b><tt>print_page</tt></b>, Ghostscript will call -<b><tt>print_page</tt></b> the requisite number of times to print the -desired number of copies; if the device provides -<b><tt>print_page_copies</tt></b>, Ghostscript will call -<b><tt>print_page_copies</tt></b> once per page, passing it the desired -number of copies. - -<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 <b><tt>WXYZ</tt></b>, the entry -in the procedure structure may be either <b><tt>gx_default_WXYZ</tt></b>, -for instance <b><tt>gx_default_tile_rectangle</tt></b>, or -<b><tt>NULL</tt></b> or 0. (The device procedure must also call the -<b><tt>gx_default_</tt></b> procedure if it doesn't implement the function -for particular values of the arguments.) Since C compilers supply 0 as the -value for omitted structure elements, this convention means that statically -initialized procedure structures continue to work even if new (optional) -members are added. - -<h3><a name="Life_cycle"></a>Life cycle</h3> - -<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: - -<blockquote><b><tt> -open_device<br> -finish_copydevice<br> -get_initial_matrix<br> -get_params<br> -put_params<br> -get_hardware_params -</tt></b></blockquote> - -<p> -When <b><tt>setdevice</tt></b> installs a device instance in the graphics -state, it checks whether the instance is closed or open. If the instance -is closed, <b><tt>setdevice</tt></b> calls the open routine, and then sets -the state to open. There is currently no user-accessible operation to -close a device instance. Device instances are only closed when they are -about to be freed, which occurs in three situations: - -<ul> -<li>When a <b><tt>restore</tt></b> occurs, if the instance was created since -the corresponding <b><tt>save</tt></b> and is in a VM being restored. I.e., -if the instance was created in local VM since a <b><tt>save</tt></b>, it -will always be closed and freed by the corresponding -<b><tt>restore</tt></b>; if it was created in global VM, it will only be -closed by the outermost <b><tt>restore</tt></b>, regardless of the save -level at the time the instance was created. - -<li>By the garbage collector, if the instance is no longer accessible. - -<li>When Ghostscript exits (terminates). -</ul> - -<h3><a name="Open_close"></a>Open, close, sync, copy</h3> - -<dl> -<dt><b><tt>int (*open_device)(P1(gx_device *))</tt></b> <b><em>[OPTIONAL]</em></b> -<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 <b><tt>open_device</tt></b> procedure directly: they should -always call <b><tt>gs_opendevice</tt></b> instead. -</dl> - -<dl> -<dt><b><tt>int (*finish_copydevice)(P2(gx_device *dev, const gx_device -*from_dev))</tt></b> <b><em>[OPTIONAL]</em></b> <dd>Perform any cleanup -required after <b><tt>copydevice</tt></b> has created a new device instance -by copying <b><tt>from_dev</tt></b>. If the copy operation should not be -allowed, this procedure should return an error; the copy will be freed. The -default implementation allows copying the device prototype, but does not -allow copying device instances, because instances may contain internal -pointers that should not be shared between copies, and there is no way to -determine this from outside the device. <b>NOTE</b>: Clients should never -call a device's <b><tt>finish_copydevice</tt></b> procedure: this procedure -is only intended for use by <b><tt>gs_copydevice[2]</tt></b>. -</dl> - -<dl> -<dt><b><tt>void (*get_initial_matrix)(P2(gx_device *, gs_matrix *))</tt></b> <b><em>[OPTIONAL]</em></b> -<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 -[<b><tt>xy</tt></b>]<b><tt>_pixels_per_inch</tt></b> on the assumption that -the origin is in the upper left corner, that is -<blockquote> -<b><tt>xx</tt></b> = <b><tt>x_pixels_per_inch</tt></b>/72, <b><tt>xy</tt></b> = 0,<br> -<b><tt>yx = 0, yy = -y_pixels_per_inch</tt></b>/72,<br> -<b><tt>tx = 0, ty = height</tt></b>. -</blockquote> -</dl> - -<dl> -<dt><b><tt>int (*sync_output)(P1(gx_device *))</tt></b> <b><em>[OPTIONAL]</em></b> -<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. -</dl> - -<dl> -<dt><b><tt>int (*output_page)(P3(gx_device *, int num_copies, int flush))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Output a fully composed page to the device. The -<b><tt>num_copies</tt></b> 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 <b><tt>flush</tt></b> -argument is true for <b><tt>showpage</tt></b>, false for -<b><tt>copypage</tt></b>. The default definition just calls -<b><tt>sync_output</tt></b>. Printer drivers should implement this by -printing and ejecting the page. -</dl> - -<dl> -<dt><b><tt>int (*close_device)(P1(gx_device *))</tt></b> <b><em>[OPTIONAL]</em></b> -<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 -<b><tt>close_device</tt></b> procedure directly: they should always call -<b><tt>gs_closedevice</tt></b> instead. -</dl> - -<h3><a name="Color_mapping"></a>Color and alpha mapping</h3> - -<p> -A given driver normally implements either <b><tt>map_rgb_color</tt></b> or -<b><tt>map_cmyk_color</tt></b>, but not both. Black-and-white drivers need -implement neither. Note that the <b><tt>map_xxx_color</tt></b> procedures -must not return <b><tt>gx_no_color_index</tt></b> (all 1s). - -<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 <b><tt>put_params</tt></b> procedure), the driver must call -<b><tt>gx_device_decache_colors(dev)</tt></b>. - -<dl> -<dt><b><tt>gx_color_index (*map_rgb_color)(P4(gx_device *, -gx_color_value red, gx_color_value green, -gx_color_value blue))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Map a RGB color to a device color. The range of legal values of the -RGB arguments is 0 to <b><tt>gx_max_color_value</tt></b>. The default -algorithm uses the <b><tt>map_cmyk_color</tt></b> procedure if the driver -supplies one, otherwise returns 1 if any of the values exceeds -<b><tt>gx_max_color_value</tt></b> / 2, 0 otherwise. - -<p> -Ghostscript assumes that for devices that have color capability (that is, -<b><tt>color_info.num_components</tt></b> > 1), -<b><tt>map_rgb_color</tt></b> returns a color index for a gray level (as -opposed to a non-gray color) iff red = green = blue. -</dl> - -<dl> -<dt><b><tt>gx_color_index (*map_cmyk_color)(P5(gx_device *, -gx_color_value cyan, gx_color_value magenta, -gx_color_value yellow, gx_color_value black))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Map a CMYK color to a device color. The range of legal values of the -CMYK arguments is 0 to <b><tt>gx_max_color_value</tt></b>. The default -algorithm calls the <b><tt>map_rgb_color</tt></b> procedure, with suitably -transformed arguments. - -<p> -Ghostscript assumes that for devices that have color capability (that is, -<b><tt>color_info.num_components</tt></b> > 1), -<b><tt>map_cmyk_color</tt></b> returns a color index for a gray level (as -opposed to a non-gray color) iff cyan = magenta = yellow. -</dl> - -<dl> -<dt><b><tt>int (*map_color_rgb)(P3(gx_device *, -gx_color_index color, gx_color_value rgb[3]))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Map a device color code to RGB values. The default algorithm returns -(0 if <b><tt>color</tt></b>==0 else <b><tt>gx_max_color_value</tt></b>) for -all three components. -</dl> - -<dl> -<dt><b><tt>gx_color_index (*map_rgb_alpha_color)(P5(gx_device *, -gx_color_value red, gx_color_value green, -gx_color_value blue, gx_color_value alpha))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Map a RGB color and an opacity value to a device color. The range of -legal values of the RGB and alpha arguments is 0 to -<b><tt>gx_max_color_value</tt></b>; <b><tt>alpha</tt></b> = 0 means -transparent, <b><tt>alpha</tt></b> = <b><tt>gx_max_color_value</tt></b> -means fully opaque. The default is to use the -<b><tt>map_rgb_color</tt></b> procedure and ignore alpha. - -<p> -Note that if a driver implements <b><tt>map_rgb_alpha_color</tt></b>, it -must also implement <b><tt>map_rgb_color</tt></b>, and must implement them -in such a way that -<b><tt>map_rgb_alpha_color(dev, r, g, b, gx_max_color_value)</tt></b> -returns the same value as -<b><tt>map_rgb_color(dev, r, g, b)</tt></b>. -</dl> - -<dl> -<dt><b><tt>int (*map_color_rgb_alpha)(P3(gx_device *, -gx_color_index color, gx_color_value rgba[4]))</tt></b> -<b><em>[OPTIONAL]</em></b> -<dd>Map a device color code to RGB and alpha values. The default -implementation calls <b><tt>map_color_rgb</tt></b> and fills in -<b><tt>gx_max_color_value</tt></b> for alpha. - -<p> -Note that if a driver implements <b><tt>map_color_rgb_alpha</tt></b>, it -must also implement <b><tt>map_color_rgb</tt></b>, and must implement them -in such a way that the first 3 values returned by -<b><tt>map_color_rgb_alpha</tt></b> are the same as the values returned by -<b><tt>map_color_rgb</tt></b>. - -<p> -Note that CMYK devices currently do not support variable opacity; alpha is -ignored on such devices. -</dl> - -<dl> -<dt><b><tt>typedef enum { go_text, -go_graphics } graphic_object_type; int -(*get_alpha_bits)(P4(gx_device *dev, -graphic_object_type type))</tt></b> <b><em>[OPTIONAL] [OBSOLETE]</em></b> -<dd>This procedure is no longer used: it is replaced by the -color_info.anti_alias member of the driver structure. However, it still -appears in the driver procedure vector for backward compatibility. It -should never be called, and drivers should not implement it. -</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. - -<dl> -<dt><b><tt>int (*fill_rectangle)(P6(gx_device *, int x, -int y, int width, int height, -gx_color_index color))</tt></b> -<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 <b><tt>width</tt></b> <= 0 or -height <= 0, <b><tt>fill_rectangle</tt></b> should return 0 -without drawing anything. - -<p> -Note that <b><tt>fill_rectangle</tt></b> is the only non-optional procedure -in the driver interface. -</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. - -<dl> -<dt><b><tt>int (*copy_mono)(P11(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Copy a monochrome image (similar to the PostScript image operator). -Each scan line is raster bytes wide. Copying begins at -(<b><tt>data_x</tt></b>,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 <b><tt>color0</tt></b> at each 0-bit, and -<b><tt>color1</tt></b> at each 1-bit: if <b><tt>color0</tt></b> or -<b><tt>color1</tt></b> is <b><tt>gx_no_color_index</tt></b>, the device -pixel is unaffected if the image bit is 0 or 1 respectively. If -<b><tt>id</tt></b> is different from <b><tt>gx_no_bitmap_id</tt></b>, it -identifies the bitmap contents unambiguously; a call with the same -<b><tt>id</tt></b> will always have the same <b><tt>data</tt></b>, -<b><tt>raster</tt></b>, and data contents. - -<p> -This operation, with -<b><tt>color0</tt></b> = <b><tt>gx_no_color_index</tt></b>, is -the workhorse for text display in Ghostscript, so implementing it -efficiently is very important. -</dl> - -<dl> -<dt><b><tt>int (*tile_rectangle)(P10(gx_device *, -const gx_tile_bitmap *tile, int x, int y, -int width, int height, gx_color_index color0, -gx_color_index color1, int phase_x, int phase_y))</tt></b> -<b><em>[OPTIONAL] [OBSOLETE]</em></b> -<dd>This procedure is still supported, but has been superseded by -<b><tt>strip_tile_rectangle</tt></b>. New drivers should implement -<b><tt>strip_tile_rectangle</tt></b>; if they cannot cope with non-zero -shift values, they should test for this explicitly and call the default -implementation (<b><tt>gx_default_strip_tile_rectangle</tt></b>) if -shift != 0. Clients should call -<b><tt>strip_tile_rectangle</tt></b>, not <b><tt>tile_rectangle</tt></b>. -</dl> - -<dl> -<dt><b><tt>int (*strip_tile_rectangle)(P10(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))</tt></b> -<b><em>[OPTIONAL]</em></b> -<dd>Tile a rectangle. Tiling consists of doing multiple -<b><tt>copy_mono</tt></b> operations to fill the rectangle with copies of -the tile. The tiles are aligned with the device coordinate system, to -avoid "seams". Specifically, the (<b><tt>phase_x</tt></b>, -<b><tt>phase_y</tt></b>) 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.) <b><tt>phase_x</tt></b> and -<b><tt>phase_y</tt></b> are guaranteed to be in the range -<em>[0..</em><b><tt>tile->width</tt></b><em>)</em> and -<em>[0..</em><b><tt>tile->height</tt></b><em>)</em> respectively. - -<p> -If <b><tt>color0</tt></b> and <b><tt>color1</tt></b> are both -<b><tt>gx_no_color_index</tt></b>, then the tile is a color pixmap, not a -bitmap: see the next section. - -<p> -This operation is the workhorse for halftone filling in Ghostscript, so -implementing it efficiently for solid tiles (that is, where either -<b><tt>color0</tt></b> and <b><tt>color1</tt></b> are both -<b><tt>gx_no_color_index</tt></b>, for colored halftones, or neither one is -<b><tt>gx_no_color_index</tt></b>, for monochrome halftones) is very -important. -</dl> - -<h4><a name="Pixmap_imaging"></a>Pixmap imaging</h4> - -<p> -Pixmaps are just like bitmaps, except that each pixel occupies more than -one bit. All the bits for each pixel are grouped together (this is -sometimes called "chunky" or "Z" format). For <b><tt>copy_color</tt></b>, -the number of bits per pixel is given by the -<b><tt>color_info.depth</tt></b> parameter in the device structure: the -legal values are 1, 2, 4, 8, 16, 24, or 32. The pixel values are device -color codes (that is, whatever it is that <b><tt>map_rgb_color</tt></b> -returns). - -<dl> -<dt><b><tt>int (*copy_color)(P9(gx_device *, -const unsigned char *data, int data_x, int raster, -gx_bitmap_id id, int x, int y, int width, -int height))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Copy a color image with multiple bits per pixel. The raster is in -bytes, but <b><tt>x</tt></b> and <b><tt>width</tt></b> are in pixels, not -bits. If <b><tt>id</tt></b> is different from -<b><tt>gx_no_bitmap_id</tt></b>, it identifies the bitmap contents -unambiguously; a call with the same <b><tt>id</tt></b> will always have the -same <b><tt>data</tt></b>, <b><tt>raster</tt></b>, and data contents. - -<p> -We do not provide a separate procedure for tiling with a pixmap; instead, -<b><tt>tile_rectangle</tt></b> can also take colored tiles. This is -indicated by the <b><tt>color0</tt></b> and <b><tt>color1</tt></b> -arguments' both being <b><tt>gx_no_color_index</tt></b>. In this case, as -for <b><tt>copy_color</tt></b>, the <b><tt>raster</tt></b> and -<b><tt>height</tt></b> in the "bitmap" are interpreted as for real bitmaps, -but the <b><tt>x</tt></b> and <b><tt>width</tt></b> are in pixels, not -bits. -</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 -(<b><tt>RasterOp</tt></b> and alpha-based), but more may be added in the -future. - -<blockquote> -<b><em>THIS AREA OF THE INTERFACE IS SOMEWHAT UNSTABLE: USE AT YOUR OWN -RISK.</em></b> -</blockquote> - -<dl> -<dt><b><tt>int (*copy_alpha)(P11(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))</tt></b> -<b><em>[OPTIONAL]</em></b> -<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 (<b><tt>data</tt></b>, <b><tt>data_x</tt></b>, and -<b><tt>raster</tt></b>) and whose color is the given color (which has -<b><em>not</em></b> been premultiplied by the alpha value), using the Sover -rule. <b><tt>depth</tt></b>, the number of bits per alpha value, is either -2 or 4, and in any case is always a value returned by a previous call on -the <b><tt>get_alpha_bits</tt></b> procedure. Note that if -<b><tt>get_alpha_bits</tt></b> always returns 1, this procedure will never -be called. -</dl> - -<dl> -<dt><b><tt>int (*create_compositor)(P5(dev_t *dev, -gx_device_t **pcdev, const gs_composite_t *pcte, -const gs_imager_state *pis, gs_memory_t *memory))</tt></b> -<b><em>[OPTIONAL]</em></b> -<dd>Create a new device (called a "compositing device" or "compositor") -that will composite data written to it with the device's existing data, -according to the compositing function defined by <b><tt>*pcte</tt></b>. -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 return themselves, which -effectively ignores the compositing function. - -<li>"Leaf" devices that do imaging and have no special optimizations for -compositing (for example, some memory devices) ask the -<b><tt>gs_composite_t</tt></b> to create a default compositor. - -<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 <b><tt>*pcte</tt></b> to determine whether it specifies -such an operation: if so, they create a specialized compositor, and if not, -they ask the <b><tt>gs_composite_t</tt></b> to create a default compositor. -</ul> - -<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> -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> -Closing a compositor frees all of its storage, including the compositor -itself. However, since the <b><tt>create_compositor</tt></b> call may -return the same device, clients must check for this case, and only call the -close procedure if a separate device was created. -</dl> - -<p> -<font size="+1"> -<b><em>[strip_]copy_rop WILL BE SUPERSEDED BY COMPOSITORS</em></b> -</font> - -<dl> -<dt><b><tt>int (*copy_rop)(P15(gx_device *dev, -const byte *sdata, int sourcex, uint sraster, -gx_bitmap_id id, const gx_color_index *scolors, -const gx_tile_bitmap *texture, -const gx_color_index *tcolors, int x, int y, -int width, int height, int phase_x, int phase_y, -int command))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>This procedure is still supported, but has been superseded by -<b><tt>strip_copy_rop</tt></b>. New drivers should implement -<b><tt>strip_copy_rop</tt></b>; if they cannot cope with non-zero shift -values in the texture, they should test for this explicitly and call the -default implementation (<b><tt>gx_default_strip_copy_rop</tt></b>) if -shift != 0. Clients should call <b><tt>strip_copy_rop</tt></b>, -not <b><tt>copy_rop</tt></b>. -</dl> - -<dl> -<dt><b><tt>int (*strip_copy_rop)(P15(gx_device *dev, -const byte *sdata, int sourcex, uint sraster, -gx_bitmap_id id, const gx_color_index *scolors, -const gx_strip_bitmap *texture, -const gx_color_index *tcolors, int x, int y, -int width, int height, int phase_x, int phase_y, -int command))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Combine an optional source image <b>S</b> (as for -<b><tt>copy_mono</tt></b> or <b><tt>copy_color</tt></b>) and an optional -texture <b>T</b> (a tile, as for <b><tt>tile_rectangle</tt></b>) with the -existing bitmap or pixmap <b>D</b> held by the driver, pixel by pixel, -using any 3-input Boolean operation as modified by "transparency" flags: -schematically, set <b>D = f(D,S,T)</b>, computing <b>f</b> in RGB -space rather than using actual device pixel values. <b>S</b> and <b>T</b> -may each (independently) be a solid color, a bitmap with "foreground" and -"background" colors, or a pixmap. This is a complex (and currently rather -slow) operation. The arguments are as follows: - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=top> <td><b><tt>dev</tt></b> - <td> - <td>the device, as for all driver procedures -<tr valign=top> <td><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>, <b><tt>sraster</tt></b>, <b><tt>id</tt></b>, <b><tt>scolors</tt></b> - <td> - <td>specify <b>S</b>, <a href="#S_spec">see below</a> -<tr valign=top> <td><b><tt>texture</tt></b>, <b><tt>tcolors</tt></b> - <td> - <td>specify <b>T</b>, <a href="#T_spec">see below</a> -<tr valign=top> <td><b><tt>x</tt></b>, <b><tt>y</tt></b>, <b><tt>width</tt></b>, <b><tt>height</tt></b> - <td> - <td>as for the other copy and fill procedures -<tr valign=top> <td><b><tt>phase_x</tt></b>, <b><tt>phase_y</tt></b> - <td> - <td>part of <b>T</b> specification, <a href="#T_spec">see below</a> -<tr valign=top> <td><b><tt>command</tt></b> - <td> - <td><a href="#F_spec">see below</a> -</table></blockquote> -</dl> - -<h5><a name="S_spec"></a>The source specification S</h5> - -<p> -As noted above, the source <b>S</b> may be a solid color, a bitmap, or a -pixmap. If <b>S</b> is a solid color: - -<ul> -<li><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>, -<b><tt>sraster</tt></b>, and <b><tt>id</tt></b> are irrelevant. - -<li><b><tt>scolors</tt></b> points to two <b><tt>gx_color_index</tt></b> -values; <b><tt>scolors[0]</tt></b> = <b><tt>scolors[1]</tt></b> = the -color. -</ul> - -<p> -If <b>S</b> is a bitmap: - -<ul> -<li><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>, -<b><tt>sraster</tt></b>, and <b><tt>id</tt></b> arguments are as for -<b><tt>copy_mono</tt></b> or <b><tt>copy_color</tt></b> -(<b><tt>data</tt></b>, <b><tt>data_x</tt></b>, <b><tt>raster</tt></b>, -<b><tt>id</tt></b>), and specify a source bitmap. - -<li><b><tt>scolors</tt></b> points to two <b><tt>gx_color_index</tt></b> -values; <b><tt>scolors[0]</tt></b> is the background color (the color -corresponding to 0-bits in the bitmap), <b><tt>scolors[1]</tt></b> is the -foreground color (the color corresponding to 1-bits in the bitmap). -</ul> - -<p> -If <b>S</b> is a pixmap: - -<ul> -<li><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>, -<b><tt>sraster</tt></b>, and <b><tt>id</tt></b> arguments are as for -<b><tt>copy_mono</tt></b> or <b><tt>copy_color</tt></b> -(<b><tt>data</tt></b>, <b><tt>data_x</tt></b>, <b><tt>raster</tt></b>, -<b><tt>id</tt></b>), and specify a source pixmap whose depth is the same as -the depth of the destination. - -<li><b><tt>scolors</tt></b> is <b><tt>NULL</tt></b>. -</ul> - -<p> -Note that if the source is a bitmap with background=0 and foreground=1, and -the destination is 1 bit deep, then the source can be treated as a pixmap -(scolors=<b><tt>NULL</tt></b>). - -<h5><a name="T_spec"></a>The texture specification T</h5> - -<p> -Similar to the source, the texture <b>T</b> may be a solid color, a bitmap, -or a pixmap. If <b>T</b> is a solid color: - -<ul> -<li>The texture pointer is irrelevant. - -<li><b><tt>tcolors</tt></b> points to two <b><tt>gx_color_index</tt></b> -values; <b><tt>tcolors[0]</tt></b> = <b><tt>tcolors[1]</tt></b> = the -color. -</ul> - -<p> -If <b>T</b> is a bitmap: - -<ul> -<li>The texture argument points to a <b><tt>gx_tile_bitmap</tt></b>, as for -the <b><tt>tile_rectangle</tt></b> procedure. Similarly, -<b><tt>phase_x</tt></b> and <b><tt>phase_y</tt></b> specify the offset of -the texture relative to the device coordinate system origin, again as for -<b><tt>tile_rectangle</tt></b>. The tile is a bitmap (1 bit per pixel). - -<li><b><tt>tcolors</tt></b> points to two <b><tt>gx_color_index</tt></b> -values; <b><tt>tcolors[0]</tt></b> is the background color (the color -corresponding to 0-bits in the bitmap), <b><tt>tcolors[1]</tt></b> is the -foreground color (the color corresponding to 1-bits in the bitmap). -</ul> - -<p> -If <b>T</b> is a pixmap: - -<ul> -<li>The texture argument points to a <b><tt>gx_tile_bitmap</tt></b> whose -depth is the same as the depth of the destination. - -<li>tcolors is <b><tt>NULL</tt></b>. -</ul> - -<p> -Again, if the texture is a bitmap with background=0 and foreground=1, and -the destination depth is 1, the texture bitmap can be treated as a pixmap -(tcolors=<b><tt>NULL</tt></b>). - -<p> -Note that while a source bitmap or pixmap has the same width and height as -the destination, a texture bitmap or pixmap has its own width and height -specified in the <b><tt>gx_tile_bitmap</tt></b> structure, and is -replicated or clipped as needed. - -<h5><a name="F_spec"></a>The function specification f</h5> - -<p> -"Command" indicates the raster operation and transparency as follows: - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=bottom> - <th>Bits - <td> - <td> -<tr valign=top> <td>7-0 - <td> - <td>raster op -<tr valign=top> <td>8 - <td> - <td>0 if source opaque, 1 if source transparent -<tr valign=top> <td>9 - <td> - <td>0 if texture opaque, 1 if texture transparent -<tr valign=top> <td>?-10 - <td> - <td>unused, must be 0 -</table></blockquote> - -<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: - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=bottom> - <th>Bit - <td> - <th>Texture - <td> - <th>Source - <td> - <th>Destination -<tr> <td colspan=7><hr> -<tr valign=top> <td align=center>7 - <td> - <td align=center>1 - <td> - <td align=center>1 - <td> - <td align=center>1 -<tr valign=top> <td align=center>6 - <td> - <td align=center>1 - <td> - <td align=center>1 - <td> - <td align=center>0 -<tr valign=top> <td align=center>5 - <td> - <td align=center>1 - <td> - <td align=center>0 - <td> - <td align=center>1 -<tr valign=top> <td align=center>4 - <td> - <td align=center>1 - <td> - <td align=center>0 - <td> - <td align=center>0 -<tr valign=top> <td align=center>3 - <td> - <td align=center>0 - <td> - <td align=center>1 - <td> - <td align=center>1 -<tr valign=top> <td align=center>2 - <td> - <td align=center>0 - <td> - <td align=center>1 - <td> - <td align=center>0 -<tr valign=top> <td align=center>1 - <td> - <td align=center>0 - <td> - <td align=center>0 - <td> - <td align=center>1 -<tr valign=top> <td align=center>0 - <td> - <td align=center>0 - <td> - <td align=center>0 - <td> - <td align=center>0 -</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 H-P -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.) - -<h5><a name="Compositing_notes"></a>Notes</h5> - -<p> -<b><tt>copy_rop</tt></b> is defined to operate on pixels in RGB space, -again following the H-P and Microsoft specification. For devices that -don't use RGB (or gray-scale with black = 0, white = all 1s) as their -native color representation, the implementation of <b><tt>copy_rop</tt></b> -must convert to RGB or gray space, do the operation, and convert back (or -do the equivalent of this). Here are the <b><tt>copy_rop</tt></b> -equivalents of the most important previous imaging calls. We assume the -declaration: - -<blockquote><b><tt> -static const gx_color_index white2[2] = { 1, 1 }; -</tt></b></blockquote> - -<p> -Note that <b><tt>rop3_S</tt></b> may be replaced by any other Boolean operation. -For monobit devices, we assume that black = 1. - -<blockquote> -<pre>/* For all devices: */ -(*fill_rectangle)(dev, x, y, w, h, color) ==> - - { gx_color_index colors[2]; - colors[0] = colors[1] = color; - (*dev_proc(dev, copy_rop))(dev, NULL, 0, 0, gx_no_bitmap_id, colors, - NULL, colors /*irrelevant*/, - x, y, w, h, 0, 0, rop3_S); - } - -/* For black-and-white devices only: */ -(*copy_mono)(dev, base, sourcex, sraster, id, - x, y, w, h, (gx_color_index)0, (gx_color_index)1) ==> - - (*dev_proc(dev, copy_rop))(dev, base, sourcex, sraster, id, NULL, - NULL, white2 /*irrelevant*/, - x, y, w, h, 0, 0, rop3_S); - -/* For color devices, where neither color0 nor color1 is gx_no_color_index: */ -(*copy_mono)(dev, base, sourcex, sraster, id, - x, y, w, h, color0, color1) ==> - - { gx_color_index colors[2]; - colors[0] = color0, colors[1] = color1; - (*dev_proc(dev, copy_rop))(dev, base, sourcex, sraster, id, colors, - NULL, white2 /*irrelevant*/, - x, y, w, h, 0, 0, rop3_S); - } - -/* For black-and-white devices only: */ -(*copy_mono)(dev, base, sourcex, sraster, id, - x, y, w, h, gx_no_color_index, (gx_color_index)1) ==> - - (*dev_proc(dev, copy_rop))(dev, base, sourcex, sraster, id, NULL, - NULL, white2 /*irrelevant*/, - x, y, w, h, 0, 0, - rop3_S | lop_S_transparent); - -/* For all devices: */ -(*copy_color)(dev, base, sourcex, sraster, id, - x, y, w, h) ==> [same as first copy_mono above] - -/* For black-and-white devices only: */ -(*tile_rectangle)(dev, tile, x, y, w, h, - (gx_color_index)0, (gx_color_index)1, px, py) ==> - - (*dev_proc(dev, copy_rop))(dev, NULL, 0, 0, gx_no_bitmap_id, - white2 /*irrelevant*/, - tile, NULL, - x, y, w, h, px, py, rop3_T) -</pre></blockquote> - -<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> -The <b><tt>fill_</tt></b>* 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. - -<dl> -<dt><b><tt>int (*fill_trapezoid)(P10(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Fill a trapezoid. The bottom and top edges are parallel to the x -axis, and are defined by <b><tt>ybot</tt></b> and <b><tt>ytop</tt></b>, -respectively. The left and right edges are defined by <b><tt>left</tt></b> -and <b><tt>right</tt></b>. Both of these respresent lines (<b><tt>gs_fixed_edge</tt></b> -is defined in <a href="../src/gxdevcli.h">gxdevcli.h</a> and consists -of <b><tt>gs_fixed_point</tt></b> <b><tt>start</tt></b> and <b><tt>end</tt></b> points). -The y coordinates of these lines need not have any specific relation to -<b><tt>ybot</tt></b> and <b><tt>ytop</tt></b>. 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 -<b><tt>swap_axes</tt></b> is set, the meanings of X and Y are -interchanged. -</dl> - -<dl> -<dt><b><tt>int (*fill_parallelogram)(P9(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<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. -</dl> - -<dl> -<dt><b><tt>int (*fill_triangle)(P9(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Fill a triangle whose corners are <em>(px,py)</em>, -<em>(px+ax,py+ay)</em>, and <em>(px+bx,py+by)</em>. -</dl> - -<dl> -<dt><b><tt>int (*draw_thin_line)(P7(gx_device *dev, -fixed fx0, fixed fy0, fixed fx1, fixed fy1, -const gx_drawing_color *pdcolor, -gs_logical_operation_t lop))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Draw a one-pixel-wide line from <em>(fx0,fy0)</em> to -<em>(fx1,fy1)</em>. -</dl> - -<dl> -<dt><b><tt>int (*draw_line)(P6(gx_device *dev, int x0, int y0, -int x1, int y1, gx_color_index color))</tt></b> -<b><em>[OPTIONAL] [OBSOLETE]</em></b> -<dd>This procedure is no longer used: it is replaced by the draw_thin_line -procedure. However, still appears in the driver procedure vector for -backward compatibility. It should never be called, and drivers should not -implement it. -</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 output formats such as CGM, 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: - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=top> <th align=left>Header - <td> - <th align=left>Defines -<tr valign=top> <td><a href="../src/gxpaint.h">gxpaint.h</a> - <td> - <td><b><tt>gx_fill_params</tt></b>, <b><tt>gx_stroke_params</tt></b> -<tr valign=top> <td><a href="../src/gxfixed.h">gxfixed.h</a> - <td> - <td><b><tt>fixed</tt></b>, <b><tt>gs_fixed_point</tt></b> (used by - <b><tt>gx_*_params</tt></b>) -<tr valign=top> <td><a href="../src/gxistate.h">gxistate.h</a> - <td> - <td><b><tt>gs_imager_state</tt></b> (used by <b><tt>gx_*_params</tt></b>) -<tr valign=top> <td><a href="../src/gxline.h">gxline.h</a> - <td> - <td><b><tt>gx_line_params</tt></b> (used by <b><tt>gs_imager_state</tt></b>) -<tr valign=top> <td><a href="../src/gslparam.h">gslparam.h</a> - <td> - <td>line cap/join values (used by <b><tt>gx_line_params</tt></b>) -<tr valign=top> <td><a href="../src/gxmatrix.h">gxmatrix.h</a> - <td> - <td><b><tt>gs_matrix_fixed</tt></b> (used by <b><tt>gs_imager_state</tt></b>) -<tr valign=top> <td><a href="../src/gspath.h">gspath.h</a>, <a href="../src/gxpath.h">gxpath.h</a>, <a href="../src/gzpath.h">gzpath.h</a> - <td> - <td><b><tt>gx_path</tt></b> -<tr valign=top> <td><a href="../src/gxcpath.h">gxcpath.h</a>, <a href="../src/gzcpath.h">gzcpath.h</a> - <td> - <td><b><tt>gx_clip_path</tt></b> -</table></blockquote> - -<p> -For a minimal example of how to implement the high-level drawing operations, -see <a href="../src/gdevtrac.c">gdevtrac.c</a>. - -<h4><a name="Paths"></a>Paths</h4> - -<dl> -<dt><b><tt>int (*fill_path)(P6(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<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 -<b><tt>NULL</tt></b>, meaning do not clip. -</dl> - -<dl> -<dt><b><tt>int (*stroke_path)(P6(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<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 -<b><tt>NULL</tt></b>, meaning not to clip. -</dl> - -<dl> -<dt><b><tt>int (*fill_mask)(P13(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))</tt></b> -<b><em>[OPTIONAL]</em></b> -<dd>Color the 1-bits in the given mask (or according to the alpha values, -if <b><tt>depth</tt></b> > 1), clipped by the given clip path, -with the given color and logical operation. The clip path pointer may be -<b><tt>NULL</tt></b>, meaning do not clip. The parameters -<b><tt>data</tt></b>, ..., <b><tt>height</tt></b> are as for -<b><tt>copy_mono</tt></b>; depth is as for <b><tt>copy_alpha</tt></b>; -command is as for <b><tt>copy_rop</tt></b>. -</dl> - -<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> -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: - -<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 -<b><tt>image_type_from_device</tt></b> (2)) are defined by: - -<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: - -<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 (<b><tt>ImageType</tt></b> 1) images -are defined by: - -<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="../src/gsiparam.h">gsiparam.h</a> and <b><tt>gsiparm*.h</tt></b>, -which define parameters for an image. - -<p> -The <b><tt>begin[_typed_]image</tt></b> driver procedures create image -enumeration structures. The common part of these structures consists of: - -<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 <b><tt>procs</tt></b> consists of: - -<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(P4(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(P3(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(P1(gx_image_enum_common_t *info)) - - image_enum_proc_flush((*flush)); - -} gx_image_enum_procs_t;</pre> -</blockquote> - -<p> In other words, <b><tt>begin[_typed]_image</tt></b> 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 -<b><tt>begin[_typed]_image</tt></b>, such as the one in <a -href="../src/gdevbbox.c">gdevbbox.c</a> or <a -href="../src/gdevps.c">gdevps.c</a>. - -<p> -The data passed at each call of <b><tt>image_plane_data</tt></b> consists of -one or more planes, as appropriate for the type of image. -<b><tt>begin[_typed]_image</tt></b> must initialize the -<b><tt>plane_depths</tt></b> array in the enumeration structure with the -depths (bits per element) of the planes. The array of -<b><tt>gx_image_plane_t</tt></b> structures passed to each call of -<b><tt>image_plane_data</tt></b> then defines where the data are stored, as -follows: - -<blockquote> -<pre>typedef struct gx_image_plane_s { - const byte *data; - int data_x; - uint raster; -} gx_image_plane_t;</pre> -</blockquote> - -<dl> -<dt><b><tt>int (*begin_image)(P9(gx_device *dev, -const gs_imager_state *pis, const gs_image_t *pim, -gs_image_format_t format, gs_int_rect *prect, -const gx_drawing_color *pdcolor, -const gx_clip_path *pcpath, gs_memory_t *memory, -gx_image_enum_common_t **pinfo))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Begin the transmission of an image. Zero or more calls of -<b><tt>image_plane_data</tt></b> will follow, and then a call of -<b><tt>end_image</tt></b>. The parameters of <b><tt>begin_image</tt></b> -are as follows: - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=top> <td><b><tt>pis</tt></b> - <td> - <td>pointer to an imager state. The only relevant elements of the - imager state are the CTM (coordinate transformation matrix), - the logical operation (<b><tt>RasterOp</tt></b> or - transparency), and the color rendering information. -<tr valign=top> <td><b><tt>pim</tt></b> - <td> - <td>pointer to the <b><tt>gs_image_t</tt></b> structure that - defines the image parameters -<tr valign=top> <td><b><tt>format</tt></b> - <td> - <td>defines how pixels are represented for - <b><tt>image_plane_data</tt></b>. See the description of - <b><tt>image_plane_data</tt></b> below -<tr valign=top> <td><b><tt>prect</tt></b> - <td> - <td>if not <b><tt>NULL</tt></b>, defines a subrectangle of the - image; only the data for this subrectangle will be passed to - <b><tt>image_plane_data</tt></b>, and only this subrectangle should - be drawn -<tr valign=top> <td><b><tt>pdcolor</tt></b> - <td> - <td>defines a drawing color, only needed for masks or if - <b><tt>CombineWithColor</tt></b> is true -<tr valign=top> <td><b><tt>pcpath</tt></b> - <td> - <td>if not <b><tt>NULL</tt></b>, defines an optional clipping path -<tr valign=top> <td><b><tt>memory</tt></b> - <td> - <td>defines the allocator to be used for allocating bookkeeping - information -<tr valign=top> <td><b><tt>pinfo</tt></b> - <td> - <td>the implementation should return a pointer to its state - structure here -</table></blockquote> - -<p> -<b><tt>begin_image</tt></b> is expected to allocate a structure for its -bookkeeping needs, using the allocator defined by the memory parameter, and -return it in <b><tt>*pinfo</tt></b>. <b><tt>begin_image</tt></b> should not assume that -the structures in <b><tt>*pim</tt></b>, <b><tt>*prect</tt></b>, or -<b><tt>*pdcolor</tt></b> will survive the call on -<b><tt>begin_image</tt></b> (except for the color space in -<b><tt>*pim->ColorSpace</tt></b>): it should copy any necessary parts of -them into its own bookkeeping structure. It may, however, assume that -<b><tt>*pis</tt></b>, <b><tt>*pcpath</tt></b>, and of course -<b><tt>*memory</tt></b> will live at least until <b><tt>end_image</tt></b> -is called. - -<p> -<b><tt>begin_image</tt></b> returns 0 normally, or 1 if the image does not -need any data. In the latter case, <b><tt>begin_image</tt></b> does not -allocate an enumeration structure. -</dl> - -<dl> -<dt><b><tt>int (*begin_typed_image)(P9(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))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>This has the same function as <b><tt>begin_image</tt></b>, except -<ul> -<li>The image may be of any <b><tt>ImageType</tt></b>, not only -<b><tt>image_type_simple</tt></b> (1); - -<li>The image format is included in the image structure, not supplied as a -separate argument; - -<li>The optional <b><tt>pmat</tt></b> argument provides a matrix that -substitutes for the one in the imager state; - -<li>For mask images, if <b><tt>pmat</tt></b> is not <b><tt>NULL</tt></b> -and the color is pure, <b><tt>pis</tt></b> may be <b><tt>NULL</tt></b>. -</ul> -</dl> - -<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. - -<dl> -<dt><b><tt>int (*image_plane_data)(P4(gx_device *dev, -gx_image_enum_common_t *info, -const gx_image_plane_t *planes, int height))</tt></b> -<dd>This call provides more of the image source data: specifically, -<b><tt>height</tt></b> rows, with <b><tt>Width</tt></b> pixels supplied for -each row. - -<p> -The data for each row are packed big-endian within each byte, as for -<b><tt>copy_color</tt></b>. The <b><tt>data_x</tt></b> (starting X position -within the row) and <b><tt>raster</tt></b> (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 <b><tt>image_plane_data</tt></b> passes complete pixels: for example, for -a chunky image with 24 bits per pixel, each call of -<b><tt>image_plane_data</tt></b> passes 3N bytes of data (specifically, -3 × Width × height). - -<p> -The interpretation of planes depends on the <b><tt>format</tt></b> member of -the <b><tt>gs_image[_common]_t</tt></b> structure: - -<ul> -<li>If the format is <b><tt>gs_image_format_chunky</tt></b>, -<b><tt>planes[0].data</tt></b> points to data in "chunky" format, in which -the components follow each other (for instance, RGBRGBRGB....) - -<li>If the format is <b><tt>gs_image_format_component_planar</tt></b>, -<b><tt>planes[0 .. N-1].data</tt></b> 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>If the format is <b><tt>gs_image_format_bit_planar</tt></b>, -<b><tt>planes[0 .. N*B-1].data</tt></b> 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. -</ul> - -<p> -If, as a result of this call, <b><tt>image_plane_data</tt></b> 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> -<b><tt>image_plane_data</tt></b>, unlike most other procedures that take bitmaps as -arguments, does not require the data to be aligned in any way. - -<p> -Note that for some image types, different planes may have different -numbers of bits per pixel, as defined in the <b><tt>plane_depths</tt></b> array. -</dl> - -<dl> -<dt><b><tt>int (*end_image)(P3(gx_device *dev, void *info, -bool draw_last))</tt></b> -<dd>Finish processing an image, either because all data have been supplied -or because the caller has decided to abandon this image. -<b><tt>end_image</tt></b> may be called at any time after -<b><tt>begin_image</tt></b>. It should free the info structure and any -subsidiary structures. If <b><tt>draw_last</tt></b> is true, it should -finish drawing any buffered lines of the image. -</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 <b><tt>begin_image</tt></b>, -<b><tt>end_image</tt></b> will almost always be called before the next -<b><tt>begin_image</tt></b> -- 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> -Note that if <b><tt>begin_[typed_]image</tt></b> 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 -<b><tt>gx_default_begin</tt></b>/<b><tt>end_image</tt></b> partway -through.) [A later revision of this document may include an example here.] - -<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. - -<dl> -<dt><b><tt>int (*text_begin)(P9(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))</tt></b> <b><em>[OPTIONAL]</em></b> - -<dd> -Begin processing text, by creating a state structure and storing it in -<b><tt>*ppte</tt></b>. The parameters of <b><tt>text_begin</tt></b> are as -follows: -</dl> - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=top> <td><b><tt>dev</tt></b> - <td> - <td>The usual pointer to the device. -<tr valign=top> <td><b><tt>pis</tt></b> - <td> - <td>A pointer to an imager state. All elements may be relevant, - depending on how the text is rendered. -<tr valign=top> <td><b><tt>text</tt></b> - <td> - <td>A pointer to the structure that defines the text operation - and parameters. See <a href="../src/gstext.h">gstext.h</a> for details. -<tr valign=top> <td><b><tt>font</tt></b> - <td> - <td>Defines the font for drawing. -<tr valign=top> <td><b><tt>path</tt></b> - <td> - <td>Defines the path where the character outline will be appended - (if the text operation includes <b><tt>TEXT_DO_...PATH</tt></b>), - and whose current point indicates where drawing should occur - and will be updated by the string width (unless the text - operation includes <b><tt>TEXT_DO_NONE</tt></b>). -<tr valign=top> <td><b><tt>pdcolor</tt></b> - <td> - <td>Defines the drawing color for the text. Only relevant if - the text operation includes <b><tt>TEXT_DO_DRAW</tt></b>. -<tr valign=top> <td><b><tt>pcpath</tt></b> - <td> - <td>If not <b><tt>NULL</tt></b>, defines an optional clipping path. - Only relevant if the text operation includes - <b><tt>TEXT_DO_DRAW</tt></b>. -<tr valign=top> <td><b><tt>memory</tt></b> - <td> - <td>Defines the allocator to be used for allocating bookkeeping - information. -<tr valign=top> <td><b><tt>ppte</tt></b> - <td> - <td>The implementation should return a pointer to its state - structure here. -</table></blockquote> - -<p> -<b><tt>text_begin</tt></b> must allocate a structure for its bookkeeping -needs, using the allocator defined by the <b><tt>memory</tt></b> parameter, -and return it in <b><tt>*ppte</tt></b>. <b><tt>text_begin</tt></b> may -assume that the structures passed as parameters will survive until text -processing is complete. - -<p> -Clients should not call the driver <b><tt>text_begin</tt></b> procedure -directly. Instead, they should call <b><tt>gx_device_text_begin</tt></b>, -which takes the same parameters and also initializes certain common elements -of the text enumeration structure, or <b><tt>gs_text_begin</tt></b>, which -takes many of the parameters from a graphics state structure. For details, -see <a href="../src/gstext.h">gstext.h</a>. - -<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 (<b><tt>TEXT_INTERVENE</tt></b> 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. - -<dl> -<dt><b><tt>int gs_text_process(P1(gs_text_enum_t *pte))</tt></b> -<dd>Continue processing text. This procedure may return 0 or a negative -error code as usual, or one of the following values (see -<a href="../src/gstext.h">gstext.h</a> for details). - -<blockquote><table cellpadding=0 cellspacing=0> -<tr valign=top> <td><b><tt>TEXT_PROCESS_RENDER</tt></b> - <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. -<tr valign=top> <td><b><tt>TEXT_PROCESS_INTERVENE</tt></b> - <td>The client has asked to intervene between characters. - This is used for <b><tt>cshow</tt></b> and <b><tt>kshow</tt></b>. -</table></blockquote> -</dl> - -<dl> -<dt><b><tt>int gs_text_release(P2(gs_text_enum_t *pte, -client_name_t cname))</tt></b> <dd>Finish processing text and release -all associated structures. Clients must call this procedure after -<b><tt>gs_text_process</tt></b> returns 0 or an error, and may call it at -any time. -</dl> - -<p> -There are numerous other procedures that clients may call during text -processing. See <a href="../src/gstext.h">gstext.h</a> for details. - -<h5><a name="Text_notes"></a>Notes</h5> - -<p> -Note that unlike many other optional procedures, the default implementation -of <b><tt>text_begin</tt></b> cannot simply return: like the default -implementation of <b><tt>begin[_typed]_image</tt></b>, it must create and -return an enumerator. Furthermore, the implementation of the -<b><tt>process</tt></b> procedure (in the enumerator structure, called by -<b><tt>gs_text_process</tt></b>) cannot simply return without doing -anything, even if it doesn't want to draw anything on the output. See the -comments in <a href="../src/gxtext.h">gxtext.h</a> for details. - -<h3><a name="Reading_bits_back"></a>Reading bits back</h3> - -<dl> -<dt><b><tt>int (*get_bits_rectangle)(P4(gx_device *dev, -const gs_int_rect *prect, gs_get_bits_params_t *params, -gs_int_rect **unread))</tt></b> <b><em>[OPTIONAL]</em></b> - -<dd> -Read a rectangle of bits back from the device. The <b><tt>params</tt></b> -structure consists of: - -<table cellpadding=0 cellspacing=0> -<tr valign=top> <td><b><tt>options</tt></b> - <td> - <td>the allowable formats for returning the data -<tr valign=top> <td><b><tt>data[32]</tt></b> - <td> - <td>pointers to the returned data -<tr valign=top> <td><b><tt>x_offset</tt></b> - <td> - <td>the X offset of the first returned pixel in data -<tr valign=top> <td><b><tt>raster</tt></b> - <td> - <td>the distance between scan lines in the returned data -</table> - -<p> -<b><tt>options</tt></b> 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. - -<blockquote><dl> -<dt><b><em>alignment</em></b> -<dd>Specifies whether the returned data must be aligned in the normal -manner for bitmaps, or whether unaligned data are acceptable. - -<dt><b><em>pointer or copy</em></b> -<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.) - -<dt><b><em>X offset</em></b> -<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 <b><tt>get_bits_rectangle</tt></b> operation itself). - -<dt><b><em>raster</em></b> -<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). - -<dt><b><em>format</em></b> -<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. - -<dt><b><em>color space</em></b> -<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. - -<dt><b><em>standard component depth</em></b> -<dd>Specifies the number of bits per component if the data are returned in -the standard color space. (Native device pixels use -<b><tt>dev</tt></b>-><b><tt>color_info.depth</tt></b> bits per pixel.) - -<dt><b><em>alpha</em></b> -<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. -</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 -<b><tt>params[].options</tt></b> to indicate the form. The returned -<b><tt>params[].options</tt></b> will normally have only one option set per -group. - -<p> -For further details on <b><tt>params</tt></b>, see <a -href="../src/gxgetbit.h">gxgetbit.h</a>. For further details on -<b><tt>options</tt></b>, see <a href="../src/gxbitfmt.h">gxbitfmt.h</a>. - -<p> -Define w = <b><tt>prect</tt></b>->q.x - <b><tt>prect</tt></b>->p.x, h -= <b><tt>prect</tt></b>->q.y - <b><tt>prect</tt></b>->p.y. If the -bits cannot be read back (for example, from a printer), return -<b><tt>gs_error_unknownerror</tt></b>; if raster bytes is not enough space -to hold <b><tt>offset_x</tt></b> + w pixels, or if the source rectangle -goes outside the device dimensions (p.x < 0 || p.y < 0 || q.x > -<b><tt>dev</tt></b>->width || q.y > <b><tt>dev</tt></b>->height), -return <b><tt>gs_error_rangecheck</tt></b>; if any regions could not be -read, return <b><tt>gs_error_ioerror</tt></b> if unpainted is -<b><tt>NULL</tt></b>, otherwise the number of rectangles (see below); -otherwise return 0. - -<p> -The caller supplies a buffer of <b><tt>raster</tt></b> × h -bytes starting at <b><tt>data[0]</tt></b> for the returned data in chunky -format, or <b><em>N</em></b> buffers of -<b><tt>raster</tt></b> × h bytes starting at -<b><tt>data[0]</tt></b> through -<b><tt>data[</tt></b><b><em>N-1</em></b><b><tt>]</tt></b> 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 -<b><tt>x_offset</tt></b> 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 <b><tt>data[0]</tt></b> or -<b><tt>data[</tt></b><b><em>0..N-1</em></b><b><tt>]</tt></b>. - -<p> -If not all the source data are available (for example, because the source -was a partially obscured window and backing store was not available or not -used), or if the rectangle does not fall completely within the device's -coordinate system, any unread bits are undefined, and the value returned -depends on whether unread is <b><tt>NULL</tt></b>. If unread is -<b><tt>NULL</tt></b>, return <b><tt>gs_error_ioerror</tt></b>; in this case, -some bits may or may not have been read. If unread is not -<b><tt>NULL</tt></b>, allocate (using <b><tt>dev</tt></b>->memory) and -fill in a list of rectangles that could not be read, store the pointer to -the list in <b><tt>*unread</tt></b>, and return the number of rectangles; in -this case, all bits not listed in the rectangle list have been read back -properly. The list is not sorted in any particular order, but the -rectangles do not overlap. Note that the rectangle list may cover a -superset of the region actually obscured: for example, a lazy implementation -could return a single rectangle that was the bounding box of the region. -</dl> - -<dl> -<dt><b><tt>int (*get_bits)(P4(gx_device *dev, int y, -byte *data, byte **actual_data))</tt></b> -<b><em>[OPTIONAL]</em></b> -<dd>Read scan line <b><tt>y</tt></b> of bits back from the device into the -area starting at data. This call is functionally equivalent to - -<blockquote> -<pre>(*get_bits_rectangle) - (dev, {0, y, dev->width, y+1}, - {(GB_ALIGN_ANY | (GB_RETURN_COPY | GB_RETURN_POINTER) | GB_OFFSET_0 | - GB_RASTER_STANDARD | GB_FORMAT_CHUNKY | GB_COLORS_NATIVE | - GB_ALPHA_NONE), - {data}})</pre></blockquote> - -<p> -with the returned value of -<b><tt>params</tt></b>-><b><tt>data[0]</tt></b> stored in -<b><tt>*actual_data</tt></b>, and will in fact be implemented this way if -the device defines a <b><tt>get_bits_rectangle</tt></b> procedure and does -not define one for <b><tt>get_bits</tt></b>. (If -<b><tt>actual_data</tt></b> is <b><tt>NULL</tt></b>, -<b><tt>GB_RETURN_POINTER</tt></b> is omitted from the options.) -</dl> - -<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, <b><tt>NULL</tt></b>, -array of integer, array of float, or arrays or dictionaries of mixed types. -For example, the <b><tt>Name</tt></b> of a device is a string; the -<b><tt>Margins</tt></b> of a device is an array of two floats. See -<a href="../src/gsparam.h">gsparam.h</a> for more details. - -<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 -<b><tt>get_params</tt></b> and <b><tt>put_params</tt></b> procedures. If -your device has parameters beyond those of a straightforward display or -printer, we strongly advise using the <b><tt>_get_params</tt></b> and -<b><tt>_put_params</tt></b> procedures in an existing device (for example, -<a href="../src/gdevcdj.c">gdevcdj.c</a> or <a -href="../src/gdevbit.c">gdevbit.c</a>) as a model for your own code. - -<dl> -<dt><b><tt>int (*get_params)(P2(gx_device *dev, -gs_param_list *plist))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Read the parameters of the device into the parameter list at -<b><tt>plist</tt></b>, using the <b><tt>param_write_*</tt></b> -macros or procedures defined in <a href="../src/gsparam.h">gsparam.h</a>. -</dl> - -<dl> -<dt><b><tt>int (*get_hardware_params)(P2(gx_device *dev, -gs_param_list *plist))</tt></b> <b><em>[OPTIONAL]</em></b> -<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 -<b><tt>gs_param_list</tt></b> [<b><tt>param_requested</tt></b>(plist, -<b><tt>key_name</tt></b>)]. This function may cause the asynchronous -rendering pipeline (if enabled) to be drained, so it should be used -sparingly. -</dl> - -<dl> -<dt><b><tt>int (*put_params)(P2(gx_device *dev, -gs_param_list *plist))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Set the parameters of the device from the parameter list at -<b><tt>plist</tt></b>, using the <b><tt>param_read_</tt></b>* -macros/procedures defined in <a href="../src/gsparam.h">gsparam.h</a>. All -<b><tt>put_params</tt></b> procedures must use a "two-phase commit" -algorithm; see <a href="../src/gsparam.h">gsparam.h</a> for details. -</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 <b><tt>get_params</tt></b>. To do -this, they create the CRD in the usual way (normally using the -<b><tt>gs_cie_render1_build</tt></b> and <b><tt>_initialize</tt></b> -procedures defined in <a href="../src/gscrd.h">gscrd.h</a>), and then write -it as a parameter using <b><tt>param_write_cie_render1</tt></b> defined in -<a href="../src/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: - -<ul> -<li>The TransformPQR element of the CRD must include a -<b><tt>proc_name</tt></b>, and optionally <b><tt>proc_data</tt></b>. The -<b><tt>proc_name</tt></b> 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, "<b><tt>bitTPQRDefault</tt></b>". - -<li>For each such named TransformPQR procedure, the driver's -<b><tt>get_param</tt></b> procedure must provide a parameter of the same -name. The parameter value must be a string whose bytes are the actual -procedure address. -</ul> - -<p> -For a complete example, see the <b><tt>bit_get_params</tt></b> procedure in -<a href="../src/gdevbit.c">gdevbit.c</a>. Note that it is essential that -the driver return the CRD or the procedure address only if specifically -requested (<b><tt>param_requested(...)</tt></b> > 0); otherwise, errors -will occur. - -<h3><a name="External_fonts"></a>External fonts</h3> - -<p> -Drivers may include the ability to display text. More precisely, they may -supply a set of procedures that in turn implement some font and text -handling capabilities, described in <a href="Xfonts.htm">a separate -document</a>. The link between the two is the driver procedure that -supplies the font and text procedures: - -<dl> -<dt><b><tt>xfont_procs *(*get_xfont_procs)(P1(gx_device *dev))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Return a structure of procedures for handling external fonts and text -display. A <b><tt>NULL</tt></b> value means that this driver doesn't -provide this capability. -</dl> - -<p> -For technical reasons, a second procedure is also needed: - -<dl> -<dt><b><tt>gx_device *(*get_xfont_device)(P1(gx_device *dev))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Return the device that implements <b><tt>get_xfont_procs</tt></b> in a -non-default way for this device, if any. Except for certain special -internal devices, this is always the device argument. -</dl> - -<h3><a name="Page_devices"></a>Page devices</h3> - -<dl> -<dt><b><tt>gx_device *(*get_page_device)(P1(gx_device *dev))</tt></b> -<b><em>[OPTIONAL]</em></b> -<dd>According to the Adobe specifications, some devices are "page devices" -and some are not. This procedure returns <b><tt>NULL</tt></b> if the -device is not a page device, or the device itself if it is a page device. -In the case of forwarding devices, <b><tt>get_page_device</tt></b> returns -the underlying page device (or <b><tt>NULL</tt></b> if the underlying -device is not a page device). -</dl> - -<h3><a name="Miscellaneous"></a>Miscellaneous</h3> - -<dl> -<dt><b><tt>int (*get_band)(P3(gx_device *dev, int y, -int *band_start))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>If the device is a band device, this procedure stores in -<b><tt>*band_start</tt></b> 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. -</dl> - -<dl> -<dt><b><tt>void (*get_clipping_box)(P2(gx_device *dev, -gs_fixed_rect *pbox))</tt></b> <b><em>[OPTIONAL]</em></b> -<dd>Stores in <b><tt>*pbox</tt></b> a rectangle that defines the device's -clipping region. For all but a few specialized devices, this is -<em>((0,0),(width,height))</em>. -</dl> - -<!-- [2.0 end contents] ==================================================== --> - -<!-- [3.0 begin visible trailer] =========================================== --> -<hr> - -<p> -<small>Copyright © 1996, 2000 Aladdin Enterprises. -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. - -<p> -<small>Ghostscript version 7.07, 17 May 2003 - -<!-- [3.0 end visible trailer] ============================================= --> - -</body> -</html> |