diff options
Diffstat (limited to 'doc/Drivers.htm')
-rw-r--r-- | doc/Drivers.htm | 898 |
1 files changed, 293 insertions, 605 deletions
diff --git a/doc/Drivers.htm b/doc/Drivers.htm index 47c5b052..577564ba 100644 --- a/doc/Drivers.htm +++ b/doc/Drivers.htm @@ -244,21 +244,20 @@ href="../devices/gdevdjet.c">gdevdjet.c</a> are good examples of this approach.< A device is represented by a structure divided into three parts:</p> <ul> -<li>procedures that are (normally) shared by all instances of each device;</li> - <li>parameters that are present in all devices but may be different for -each device or instance; and</li> +each device or instance;</li> + +<li>an initialize_device_procs procedure; and</li> <li>device-specific parameters that may be different for each instance.</li> </ul> <p> -Normally the procedure structure is defined and initialized at compile -time. A prototype of the parameter structure (including both generic and +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 <code>const</code>, but for backward -compatibility reasons the latter is not.</p> +is copied and filled in when an instance of the device is created. This +structure should be declared as <code>const</code>, but for backward +compatibility reasons it is not.</p> <p> The <code>gx_device_common</code> macro defines the common structure @@ -275,7 +274,7 @@ href="../base/gdevprn.h">gdevprn.h</a>.</p> } 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>initialize_device_procs,</em></b> <b><em>... device-specific parameter values if any ...</em></b> };</pre> </blockquote> @@ -285,6 +284,49 @@ The device structure instance <b>must</b> have the name name used in <code>contrib.mak</code>. <code>gx_device_common</code> is a macro consisting only of the element definitions. </p> <p> +The <code>initialize_device_procs</code> function pointer is called when +the device is created. Its sole job is to initialize the entries in +the device procedure table. On entry, the device procedure table will +be full of NULL pointers. On exit, any NULLs left in the table will be +filled in with pointers to the default routines. Therefore, the routine +should set any non-default entries itself. +<p> +Devices that are (in object-oriented terms) derived from 'base' classes +(for instance a new printer device that derives from the <code>prn</code> +device) can call provided helper functions for setting the standard +functions for that base class. +<p> +For example, if the smurf device was a printer device, its +<code>initialize_device_procs</code> procedure might look like:</p> +<blockquote> +<pre>static void smurf_initialize_device_procs(gx_device *dev) { + /* We are derived from a prn device, and can print in the background */ + gdev_prn_initialize_bg(dev); + + /* Override functions for our specifics */ + set_dev_proc(dev, map_color_rgb, smurf_map_color_rgb); + set_dev_proc(dev, map_rgb_color, smurf_map_rgb_color); + ... +}</pre> +</blockquote> +<p> +The initialize procedure function pointer does not live in the in the +device procedure table (and as such is statically initialized at compile +time). Nonetheless, we refer to this as being a device procedure in the +rest of the discussion here. +<p> +Note that the <code>initialize_device_procs</code> function may be called +with a pointer to a <code>gx_device</code> rather than to the derived +device class. This happens frequently when one device wants to obtain +the prototype of another to copy device procedures around. Initialization +of items in the device other than device procs should therefore be +reserved for the <code>initialize_device</code> device procedure. +<p> +The use of the initialize procedure is new to Ghostscript 9.55. Previous +versions used a statically initialized table of device procedures. We +changed to a dynamically initialized system to more easily cope with +future changes to the device procedures. +<p> All the device procedures are called with the device as the first argument. Since each device type is actually a different structure type, the device procedures must be declared as taking a <code>gx_device *</code> as @@ -1093,8 +1135,8 @@ the same way.</p> <p>As from Ghostscript 9.11 onwards, a new device function, <tt>process_page</tt> has been introduced to solve this. A printer driver will be called via the <tt>print_page</tt> or <tt>print_page_copies</tt> entry point as before, but -rather than requesting a scan line or rectangle of pixels at a time (by -calling <tt>get_bits</tt> or <tt>get_bits_rectangle</tt> respectively), the +rather than requesting a rectangle of pixels at a time (by +calling <tt>get_bits_rectangle</tt>), the driver can now invite Ghostscript to "process the page" in whatever sized chunks it chooses.</p> @@ -1221,23 +1263,31 @@ help accelerate devices such as <tt>pdfwrite</tt> or <tt>ps2write</tt>.</p> Most of the procedures that a driver may implement are optional. If a device doesn't supply an optional procedure <code>WXYZ</code>, the entry in the procedure structure may be either <code>gx_default_WXYZ</code>, -for instance <code>gx_default_tile_rectangle</code>, or +for instance <code>gx_default_strip_tile_rectangle</code>, or <code>NULL</code> or 0. (The device procedure must also call the <code>gx_default_</code> procedure if it doesn't implement the function -for particular values of the arguments.) Since 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) +for particular values of the arguments.) Since, by construction, +device procedure entries are set to 0 at creation time, ones that are +not explicitly initialised will continue to work even if new (optional) members are added.</p> <h3><a name="Life_cycle"></a>Life cycle</h3> <p> +When a device is first created, it will have an empty device procs +table. The system will call the device's <code>initialize_device_procs</code> +function pointer to fill out this table. This operation can never fail.</p> + +<p>NOTE: This operation is also used for creating temporary 'prototype' +devices for copying device procedures from.</p> + +<p> A device instance begins life in a closed state. In this state, no output operations will occur. Only the following procedures may be called:</p> <blockquote><code> +initialize_device<br> open_device<br> -finish_copydevice<br> get_initial_matrix<br> get_params<br> put_params<br> @@ -1281,6 +1331,30 @@ level at the time the instance was created.</li> <h3><a name="Open_close"></a>Open, close, sync, copy</h3> <dl> +<dt><code>void (*initialize_device_procs)(gx_device *dev)</code></dt> <dd>Called +once a new device instance has been created. The function should initialize +the device procedure tables. This cannot fail. +<b>NOTE</b>: Clients should rarely need to call a device's +<code>initialize_device_procs</code> procedure: this procedure is mostly used +by the internal device creation code. The sole exception here is when +a device implementation wishes to copy device function pointers from another +device; then a blank <code>gx_device</code> can be created, and +<code>initialize_device_procs</code> can be used to fill out the device procs +table so it can be copied from.</dd> +</dl> + +<dl> +<dt><code>int (*initialize_device)(gx_device *dev)</code> <b><em>[OPTIONAL</em></b></dt> +<dd>Called once a new device instance has been created and the device procs +table has been initialized. This function should perform the minimum +initialization to any internal device state required. If the initial setup +fails, this procedure should return an error; the new instance will be freed. +<b>NOTE</b>: Clients should never call a device's <code>initialize_device</code> +procedure: this procedure is only intended for use by the internal device +creation code.</dd> +</dl> + +<dl> <dt><code>int (*open_device)(gx_device *)</code> <b><em>[OPTIONAL]</em></b></dt> <dd>Open the device: do any initialization associated with making the device instance valid. This must be done before any output to the device. The @@ -1290,20 +1364,6 @@ always call <code>gs_opendevice</code> instead.</dd> </dl> <dl> -<dt><code>int (*finish_copydevice)(gx_device *dev, const gx_device -*from_dev)</code> <b><em>[OPTIONAL]</em></b></dt> <dd>Perform any cleanup -required after <code>copydevice</code> has created a new device instance -by copying <code>from_dev</code>. 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 <code>finish_copydevice</code> procedure: this procedure -is only intended for use by <code>gs_copydevice[2]</code>. </dd> -</dl> - -<dl> <dt><code>void (*get_initial_matrix)(gx_device *, gs_matrix *)</code> <b><em>[OPTIONAL]</em></b> </dt> <dd>Construct the initial transformation matrix mapping user coordinates (nominally 1/72 inch per unit) to device coordinates. The default @@ -1436,19 +1496,30 @@ supported by the device.</p> <dl> <dt><code>const gx_cm_color_map_procs * get_color_mapping_procs(const -gx_device * dev)</code> <b><em>[OPTIONAL]</em></b> </dt> -<dd>This procedure returns a list of three procedures. These procedures -are used to translate values in either Gray, RGB, or CMYK color spaces -into device colorant values. A separate procedure is not required for the -DeviceN and Separation color spaces since these already represent -device colorants.</dd> +gx_device * dev, const gx_device ** tdev)</code> <b><em>[OPTIONAL]</em></b> </dt> +<dd>This procedure returns a list of three procedures, together with the +device to pass to them. These procedures are used to translate values in +either Gray, RGB, or CMYK color spaces into device colorant values. A +separate procedure is not required for the DeviceN and Separation color +spaces since these already represent device colorants.</dd> + +<p>In many cases, the device returned in <code>tdev</code> will be the +same as <code>dev</code>, but the caller should not rely on this. For +cases where we have a chain of devices (perhaps because of a subclass +or compositor device having been introduced internally as part of the +rendering process), the actual device that needs to do the color mapping +may be a child device of the original one. In such cases <code>tdev</code> +will be returned as a different value to <code>dev</code>. +</p> <p> The default procedure returns a list of procedures based upon <code>color_info.num_components</code>. These procedures are appropriate for DeviceGray, DeviceRGB, or DeviceCMYK process color model devices. A procedure must be defined if another process color model is used by the -device or spot colors are to be supported.</p> +device or spot colors are to be supported. All these procedures take a +<code>gx_device</code> pointer; these should be called with the value +returned in <code>tdev</code> NOT the initial value of <code>dev</code>.</p> </dl> <dl> @@ -1477,54 +1548,13 @@ the values in <code>color_info.depth</code> and </dl> <dl> -<dt><code>gx_color_index (*map_rgb_alpha_color)(gx_device *, -gx_color_value red, gx_color_value green, -gx_color_value blue, gx_color_value alpha)</code> <b><em>[OPTIONAL]</em></b></dt> -<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 -<code>gx_max_color_value</code>; <code>alpha</code> = 0 means -transparent, <code>alpha</code> = <code>gx_max_color_value</code> -means fully opaque. The default is to use the -<code>encode_color</code> procedure and ignore alpha.</dd> - -<p> -Note that if a driver implements <code>map_rgb_alpha_color</code>, it -must also implement <code>encode_color</code>, and must implement them -in such a way that -<code>map_rgb_alpha_color(dev, r, g, b, gx_max_color_value)</code> -returns the same value as -<code>encode_color(dev, CV)</code>. </p> -</dl> - -<dl> -<dt><code>int (*map_color_rgb_alpha)(gx_device *, -gx_color_index color, gx_color_value rgba[4])</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>Map a device color code to RGB and alpha values. The default -implementation calls <code>map_color_rgb</code> and fills in -<code>gx_max_color_value</code> for alpha.</dd> - -<p> -Note that if a driver implements <code>map_color_rgb_alpha</code>, it -must also implement <code>decode_color</code>, and must implement them -in such a way that the first 3 values returned by -<code>map_color_rgb_alpha</code> are the same as the values returned by -<code>decode_color</code>.</p> - -<p> -Note that only RGB devices currently support variable opacity; alpha is ignored -on other devices. The PDF 1.4 transparency features are supported on all devices. </p> -</dl> - -<dl> <dt><code>typedef enum { go_text, go_graphics } graphic_object_type; int (*get_alpha_bits)(gx_device *dev, -graphic_object_type type)</code> <b><em>[OPTIONAL] [OBSOLETE]</em></b></dt> -<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.</dd> +graphic_object_type type)</code> <b><em>[OPTIONAL]</em></b></dt> +<dd>This procedure returns the number of bits to use for anti-aliasing. +The default implementation simply returns the color_info.anti_alias +member of the driver structure.</dd> </dl> <dl> @@ -1601,21 +1631,6 @@ efficiently is very important.</p> </dl> <dl> -<dt><code>int (*tile_rectangle)(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)</code> -<b><em>[OPTIONAL] [OBSOLETE]</em></b></dt> -<dd>This procedure is still supported, but has been superseded by -<code>strip_tile_rectangle</code>. New drivers should implement -<code>strip_tile_rectangle</code>; if they cannot cope with non-zero -shift values, they should test for this explicitly and call the default -implementation (<code>gx_default_strip_tile_rectangle</code>) if -shift != 0. Clients should call -<code>strip_tile_rectangle</code>, not <code>tile_rectangle</code>.</dd> -</dl> - -<dl> <dt><code>int (*strip_tile_rectangle)(gx_device *, const gx_strip_bitmap *tile, int x, int y, int width, int height, gx_color_index color0, @@ -1691,7 +1706,7 @@ than or equal to the plane_height.</dd> <p> We do not provide a separate procedure for tiling with a pixmap; instead, -<code>tile_rectangle</code> can also take colored tiles. This is +<code>strip_tile_rectangle</code> can also take colored tiles. This is indicated by the <code>color0</code> and <code>color1</code> arguments' both being <code>gx_no_color_index</code>. In this case, as for <code>copy_color</code>, the <code>raster</code> and @@ -1818,13 +1833,19 @@ than a gx_color_index.</dd> </dl> <dl> -<dt><code>int (*create_compositor)(dev_t *dev, +<dt><code>int (*composite)(dev_t *dev, gx_device_t **pcdev, const gs_composite_t *pcte, const gs_imager_state *pis, gs_memory_t *memory)</code> <b><em>[OPTIONAL]</em></b> </dt> -<dd>Create a new device (called a "compositing device" or "compositor") -that will composite data written to it with the device's existing data, +<dd>Requests that a device perform a compositing operation; the device +should composite data written to it with the device's existing data, according to the compositing function defined by <code>*pcte</code>. +If a device cannot perform such an operation itself, it will create a +compositor device to wrap itself that will perform such operations for +it. Accordingly, the caller must watch the return values from this +function to understand if a new device has been created to which future +calls should be made. +<p> Devices will normally implement this in one of the following standard ways:</dd> <ul> @@ -1883,370 +1904,11 @@ even if the underlying device doesn't.</p> <p> Closing a compositor frees all of its storage, including the compositor -itself. However, since the <code>create_compositor</code> call may +itself. However, since the <code>composite</code> call may return the same device, clients must check for this case, and only call the close procedure if a separate device was created.</p> </dl> -<p> -<font size="+1"> -<b><em>[strip_]copy_rop WILL BE SUPERSEDED BY COMPOSITORS</em></b> -</font></p> - -<dl> -<dt><code>int (*copy_rop)(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)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>This procedure is still supported, but has been superseded by -<code>strip_copy_rop</code>. New drivers should implement -<code>strip_copy_rop</code>; if they cannot cope with non-zero shift -values in the texture, they should test for this explicitly and call the -default implementation (<code>gx_default_strip_copy_rop</code>) if -shift != 0. Clients should call <code>strip_copy_rop</code>, -not <code>copy_rop</code>.</dd> -</dl> - -<dl> -<dt><code>int (*strip_copy_rop)(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)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Combine an optional source image <b>S</b> (as for -<code>copy_mono</code> or <code>copy_color</code>) and an optional -texture <b>T</b> (a tile, as for <code>tile_rectangle</code>) 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:</dd> - -<blockquote><table> -<tr valign="top"> <td><code>dev</code></td> - <td> </td> - <td>the device, as for all driver procedures</td></tr> -<tr valign="top"> <td><code>sdata</code>, <code>sourcex</code>, <code>sraster</code>, <code>id</code>, <code>scolors</code></td> - <td> </td> - <td>specify <b>S</b>, <a href="#S_spec">see below</a></td></tr> -<tr valign="top"> <td><code>texture</code>, <code>tcolors</code></td> - <td> </td> - <td>specify <b>T</b>, <a href="#T_spec">see below</a></td></tr> -<tr valign="top"> <td><code>x</code>, <code>y</code>, <code>width</code>, <code>height</code></td> - <td> </td> - <td>as for the other copy and fill procedures</td></tr> -<tr valign="top"> <td><code>phase_x</code>, <code>phase_y</code></td> - <td> </td> - <td>part of <b>T</b> specification, <a href="#T_spec">see below</a></td></tr> -<tr valign="top"> <td><code>command</code></td> - <td> </td> - <td><a href="#F_spec">see below</a></td></tr> -</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:</p> - -<ul> -<li><code>sdata</code>, <code>sourcex</code>, -<code>sraster</code>, and <code>id</code> are irrelevant.</li> - -<li><code>scolors</code> points to two <code>gx_color_index</code> -values; <code>scolors[0]</code> = <code>scolors[1]</code> = the -color.</li> -</ul> - -<p> -If <b>S</b> is a bitmap:</p> - -<ul> -<li><code>sdata</code>, <code>sourcex</code>, -<code>sraster</code>, and <code>id</code> arguments are as for -<code>copy_mono</code> or <code>copy_color</code> -(<code>data</code>, <code>data_x</code>, <code>raster</code>, -<code>id</code>), and specify a source bitmap.</li> - -<li><code>scolors</code> points to two <code>gx_color_index</code> -values; <code>scolors[0]</code> is the background color (the color -corresponding to 0-bits in the bitmap), <code>scolors[1]</code> is the -foreground color (the color corresponding to 1-bits in the bitmap).</li> -</ul> - -<p> -If <b>S</b> is a pixmap:</p> - -<ul> -<li><code>sdata</code>, <code>sourcex</code>, -<code>sraster</code>, and <code>id</code> arguments are as for -<code>copy_mono</code> or <code>copy_color</code> -(<code>data</code>, <code>data_x</code>, <code>raster</code>, -<code>id</code>), and specify a source pixmap whose depth is the same as -the depth of the destination.</li> - -<li><code>scolors</code> is <code>NULL</code>.</li> -</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=<code>NULL</code>).</p> - -<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:</p> - -<ul> -<li>The texture pointer is irrelevant.</li> - -<li><code>tcolors</code> points to two <code>gx_color_index</code> -values; <code>tcolors[0]</code> = <code>tcolors[1]</code> = the -color.</li> -</ul> - -<p> -If <b>T</b> is a bitmap:</p> - -<ul> -<li>The texture argument points to a <code>gx_tile_bitmap</code>, as for -the <code>tile_rectangle</code> procedure. Similarly, -<code>phase_x</code> and <code>phase_y</code> specify the offset of -the texture relative to the device coordinate system origin, again as for -<code>tile_rectangle</code>. The tile is a bitmap (1 bit per pixel).</li> - -<li><code>tcolors</code> points to two <code>gx_color_index</code> -values; <code>tcolors[0]</code> is the background color (the color -corresponding to 0-bits in the bitmap), <code>tcolors[1]</code> is the -foreground color (the color corresponding to 1-bits in the bitmap).</li> -</ul> - -<p> -If <b>T</b> is a pixmap:</p> - -<ul> -<li>The texture argument points to a <code>gx_tile_bitmap</code> whose -depth is the same as the depth of the destination.</li> - -<li>tcolors is <code>NULL</code>.</li> -</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=<code>NULL</code>).</p> - -<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 <code>gx_tile_bitmap</code> structure, and is -replicated or clipped as needed.</p> - -<h5><a name="F_spec"></a>The function specification f</h5> - -<p> -"Command" indicates the raster operation and transparency as follows:</p> - -<blockquote><table> -<tr valign="bottom"> - <th colspan ="3">Bits</th> -</tr> -<tr valign="top"> <td>7-0</td> - <td> </td> - <td>raster op</td></tr> -<tr valign="top"> <td>8</td> - <td> </td> - <td>0 if source opaque, 1 if source transparent</td></tr> -<tr valign="top"> <td>9</td> - <td> </td> - <td>0 if texture opaque, 1 if texture transparent</td></tr> -<tr valign="top"> <td>10</td> - <td> </td> - <td>1 if pdf transparency is in use, 0 otherwise. This makes no -difference to the rendering, but forces the raster operation to be considered - non-idempotent by internal routines.</td></tr> -<tr valign="top"> <td>11</td> - <td> </td> - <td>1 if the target of this operation is a specific plane, rather -than all planes. The plane in question is given by bits 13 upwards. This -is only used by the planar device.</td></tr> -<tr valign="top"> <td>12-</td> - <td> </td> - <td>If bit 11 = 1, then bits 12 upwards give the plane number to - operate on. Otherwise, should be set to 0.</td></tr> -</table></blockquote> - -<p>In general most devices should just check to see that bits they do not -handle (11 and above typically) are zero, and should jump to the default - implementation, or return an error otherwise.</p> - -<p> -The raster operation follows the Microsoft and H-P specification. It is an -8-element truth table that specifies the output value for each of the -possible 2×2×2 input values as follows:</p> - -<blockquote><table> -<tr valign="bottom"> - <th>Bit</th> - <th> </th> - <th>Texture</th> - <th> </th> - <th>Source</th> - <th> </th> - <th>Destination</th></tr> -<tr valign="top"> <td align="center">7</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">6</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">0</td></tr> -<tr valign="top"> <td align="center">5</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">4</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">0</td></tr> -<tr valign="top"> <td align="center">3</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">2</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">1</td> - <td> </td> - <td align="center">0</td></tr> -<tr valign="top"> <td align="center">1</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">1</td></tr> -<tr valign="top"> <td align="center">0</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">0</td> - <td> </td> - <td align="center">0</td></tr> -</table></blockquote> - -<p> -Transparency affects the output in the following way. A source or texture -pixel is considered transparent if its value is all 1s (for instance, 1 for -bitmaps, <tt>0xffffff</tt> for 24-bit RGB pixmaps) <b><em>and</em></b> the -corresponding transparency bit is set in the command. For each pixel, the -result of the Boolean operation is written into the destination iff neither -the source nor the texture pixel is transparent. (Note that the HP -RasterOp specification, on which this is based, specifies that if the -source and texture are both all 1s and the command specifies transparent -source and opaque texture, the result <b><em>should</em></b> be written in - the output. We think this is an error in the documentation.) </p> - -<h5><a name="Compositing_notes"></a>Notes</h5> - -<p> -<code>copy_rop</code> is defined to operate on pixels in RGB space, -again following the HP 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 <code>copy_rop</code> -must convert to RGB or gray space, do the operation, and convert back (or -do the equivalent of this). Here are the <code>copy_rop</code> -equivalents of the most important previous imaging calls. We assume the -declaration: </p> - -<blockquote><code> -static const gx_color_index white2[2] = { 1, 1 }; -</code></blockquote> - -<p> -Note that <code>rop3_S</code> may be replaced by any other Boolean operation. -For monobit devices, we assume that black = 1.</p> - -<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> @@ -2307,15 +1969,6 @@ gs_logical_operation_t lop)</code> <b><em>[OPTIONAL]</em></b></dt> <dd>Draw a one-pixel-wide line from <em>(fx0,fy0)</em> to <em>(fx1,fy1)</em>.</dd> -<dt><code>int (*draw_line)(gx_device *dev, int x0, int y0, -int x1, int y1, gx_color_index color)</code> -<b><em>[OPTIONAL] [OBSOLETE]</em></b></dt> -<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.</dd> -</dl> - <h3><a name="Linear_color_drawing"></a>Linear color drawing</h3> <p> @@ -2580,9 +2233,131 @@ with the given color and logical operation. The clip path pointer may be <code>NULL</code>, meaning do not clip. The parameters <code>data</code>, ..., <code>height</code> are as for <code>copy_mono</code>; depth is as for <code>copy_alpha</code>; -command is as for <code>copy_rop</code>.</dd> +command is as below.</dd> </dl> +<h5><a name="F_spec"></a>The function specification f</h5> + +<p> +"Command" indicates the raster operation and transparency as follows:</p> + +<blockquote><table> +<tr valign="bottom"> + <th colspan ="3">Bits</th> +</tr> +<tr valign="top"> <td>7-0</td> + <td> </td> + <td>raster op</td></tr> +<tr valign="top"> <td>8</td> + <td> </td> + <td>0 if source opaque, 1 if source transparent</td></tr> +<tr valign="top"> <td>9</td> + <td> </td> + <td>0 if texture opaque, 1 if texture transparent</td></tr> +<tr valign="top"> <td>10</td> + <td> </td> + <td>1 if pdf transparency is in use, 0 otherwise. This makes no +difference to the rendering, but forces the raster operation to be considered + non-idempotent by internal routines.</td></tr> +<tr valign="top"> <td>11</td> + <td> </td> + <td>1 if the target of this operation is a specific plane, rather +than all planes. The plane in question is given by bits 13 upwards. This +is only used by the planar device.</td></tr> +<tr valign="top"> <td>12-</td> + <td> </td> + <td>If bit 11 = 1, then bits 12 upwards give the plane number to + operate on. Otherwise, should be set to 0.</td></tr> +</table></blockquote> + +<p>In general most devices should just check to see that bits they do not +handle (11 and above typically) are zero, and should jump to the default + implementation, or return an error otherwise.</p> + +<p> +The raster operation follows the Microsoft and H-P specification. It is an +8-element truth table that specifies the output value for each of the +possible 2×2×2 input values as follows:</p> + +<blockquote><table> +<tr valign="bottom"> + <th>Bit</th> + <th> </th> + <th>Texture</th> + <th> </th> + <th>Source</th> + <th> </th> + <th>Destination</th></tr> +<tr valign="top"> <td align="center">7</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">1</td></tr> +<tr valign="top"> <td align="center">6</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">0</td></tr> +<tr valign="top"> <td align="center">5</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">1</td></tr> +<tr valign="top"> <td align="center">4</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">0</td></tr> +<tr valign="top"> <td align="center">3</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">1</td></tr> +<tr valign="top"> <td align="center">2</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">1</td> + <td> </td> + <td align="center">0</td></tr> +<tr valign="top"> <td align="center">1</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">1</td></tr> +<tr valign="top"> <td align="center">0</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">0</td> + <td> </td> + <td align="center">0</td></tr> +</table></blockquote> + +<p> +Transparency affects the output in the following way. A source or texture +pixel is considered transparent if its value is all 1s (for instance, 1 for +bitmaps, <tt>0xffffff</tt> for 24-bit RGB pixmaps) <b><em>and</em></b> the +corresponding transparency bit is set in the command. For each pixel, the +result of the Boolean operation is written into the destination iff neither +the source nor the texture pixel is transparent. (Note that the HP +RasterOp specification, on which this is based, specifies that if the +source and texture are both all 1s and the command specifies transparent +source and opaque texture, the result <b><em>should</em></b> be written in + the output. We think this is an error in the documentation.) </p> + <h4><a name="Images"></a>Images</h4> <p> @@ -2747,15 +2522,16 @@ follows:</p> </blockquote> <dl> -<dt><code>int (*begin_image)(gx_device *dev, -const gs_imager_state *pis, const gs_image_t *pim, -gs_image_format_t format, gs_int_rect *prect, +<dt><code>int (*begin_typed_image)(gx_device *dev, +const gs_imager_state *pis, const gs_matrix *pmat, +const gs_image_common_t *pim, gs_int_rect *prect, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *memory, gx_image_enum_common_t **pinfo)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Begin the transmission of an image. Zero or more calls of -<code>image_plane_data</code> will follow, and then a call of -<code>end_image</code>. The parameters of <code>begin_image</code> +<dd>Begin the transmission of an image. Zero or more calls of the + <code>image_plane_data</code> function supplied in the returned image + enumerator will follow, and then a call of +<code>end_image</code>. The parameters of <code>begin_typed_image</code> are as follows:</dd> <blockquote><table> @@ -2764,16 +2540,19 @@ are as follows:</dd> <td>pointer to an imager state. The only relevant elements of the imager state are the CTM (coordinate transformation matrix), the logical operation (<code>RasterOp</code> or - transparency), and the color rendering information.</td></tr> + transparency), and the color rendering information. For + mask images, if <code>pmat</code> is not NULL and the color is pure, + <code>pis</code> may be NULL.</td></tr> +<tr valign="top"> <td><code>pmat</code></td> + <td> </td> + <td>pointer to a <code>gs_matrix</code> structure that + defines the image transformation matrix. If <code>pis</code> is non-NULL, + and <code>pmat</code> is NULL, then the <code>ctm</code> from <code>pis</code> + should be used.</td></tr> <tr valign="top"> <td><code>pim</code></td> <td> </td> <td>pointer to the <code>gs_image_t</code> structure that defines the image parameters</td></tr> -<tr valign="top"> <td><code>format</code></td> - <td> </td> - <td>defines how pixels are represented for - <code>image_plane_data</code>. See the description of - <code>image_plane_data</code> below</td></tr> <tr valign="top"> <td><code>prect</code></td> <td> </td> <td>if not <code>NULL</code>, defines a subrectangle of the @@ -2798,12 +2577,12 @@ are as follows:</dd> </table></blockquote> <p> -<code>begin_image</code> is expected to allocate a structure for its +<code>begin_typed_image</code> is expected to allocate a structure for its bookkeeping needs, using the allocator defined by the memory parameter, and -return it in <code>*pinfo</code>. <code>begin_image</code> should not assume that +return it in <code>*pinfo</code>. <code>begin_typed_image</code> should not assume that the structures in <code>*pim</code>, <code>*prect</code>, or <code>*pdcolor</code> will survive the call on -<code>begin_image</code> (except for the color space in +<code>begin_typed_image</code> (except for the color space in <code>*pim->ColorSpace</code>): it should copy any necessary parts of them into its own bookkeeping structure. It may, however, assume that <code>*pis</code>, <code>*pcpath</code>, and of course @@ -2811,33 +2590,14 @@ them into its own bookkeeping structure. It may, however, assume that is called.</p> <p> -<code>begin_image</code> returns 0 normally, or 1 if the image does not -need any data. In the latter case, <code>begin_image</code> does not +<code>begin_typed_image</code> returns 0 normally, or 1 if the image does not +need any data. In the latter case, <code>begin_typed_image</code> does not allocate an enumeration structure.</p> </dl> -<dl> -<dt><code>int (*begin_typed_image)(gx_device *dev, -const gs_imager_state *pis, const gs_matrix *pmat, -const gs_image_common_t *pim, gs_int_rect *prect, -const gx_drawing_color *pdcolor, -const gx_clip_path *pcpath, gs_memory_t *memory, -gx_image_enum_common_t **pinfo)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>This has the same function as <code>begin_image</code>, except</dd> -<ul> -<li>The image may be of any <code>ImageType</code>, not only -<code>image_type_simple</code> (1);</li> - -<li>The image format is included in the image structure, not supplied as a -separate argument;</li> - -<li>The optional <code>pmat</code> argument provides a matrix that -substitutes for the one in the imager state;</li> - -<li>For mask images, if <code>pmat</code> is not <code>NULL</code> -and the color is pure, <code>pis</code> may be <code>NULL</code>.</li> -</ul> -</dl> +<p> +The format of the image (how pixels are represented) is given by +<code>pim->format</code>.</p> <p> The actual transmission of data uses the procedures in the enumeration @@ -2914,7 +2674,7 @@ bool draw_last)</code></dt> <dd>Finish processing an image, either because all data have been supplied or because the caller has decided to abandon this image. <code>end_image</code> may be called at any time after -<code>begin_image</code>. It should free the info structure and any +<code>begin_typed_image</code>. It should free the info structure and any subsidiary structures. If <code>draw_last</code> is true, it should finish drawing any buffered lines of the image.</dd> </dl> @@ -2923,14 +2683,14 @@ finish drawing any buffered lines of the image.</dd> <p> While there will almost never be more than one image enumeration in -progress -- that is, after a <code>begin_image</code>, +progress -- that is, after a <code>begin_typed_image</code>, <code>end_image</code> will almost always be called before the next -<code>begin_image</code> -- driver code should not rely on this +<code>begin_typed_image</code> -- driver code should not rely on this property; in particular, it should store all information regarding the image in the info structure, not in the driver structure.</p> <p> -Note that if <code>begin_[typed_]image</code> saves its parameters in +Note that if <code>begin_typed_image</code> saves its parameters in the info structure, it can decide on each call whether to use its own algorithms or to use the default implementation. (It may need to call <code>gx_default_begin</code>/<code>end_image</code> partway @@ -2947,9 +2707,8 @@ optional.</p> <dl> <dt><code>int (*text_begin)(gx_device *dev, gs_imager_state *pis, const gs_text_params_t *text, -gs_font *font, gx_path *path, -const gx_device_color *pdcolor, -const gx_clip_path *pcpath, gs_memory_t *memory, +gs_font *font, +const gx_clip_path *pcpath, gs_text_enum_t **ppte)</code> <b><em>[OPTIONAL]</em></b></dt> <p></p><dd> @@ -2973,26 +2732,11 @@ follows:</dd> <tr valign="top"> <td><code>font</code></td> <td> </td> <td>Defines the font for drawing.</td></tr> -<tr valign="top"> <td><code>path</code></td> - <td> </td> - <td>Defines the path where the character outline will be appended - (if the text operation includes <code>TEXT_DO_...PATH</code>), - and whose current point indicates where drawing should occur - and will be updated by the string width (unless the text - operation includes <code>TEXT_DO_NONE</code>).</td> -<tr valign="top"> <td><code>pdcolor</code></td> - <td> </td> - <td>Defines the drawing color for the text. Only relevant if - the text operation includes <code>TEXT_DO_DRAW</code>.</td></tr> <tr valign="top"> <td><code>pcpath</code></td> <td> </td> <td>If not <code>NULL</code>, defines an optional clipping path. Only relevant if the text operation includes <code>TEXT_DO_DRAW</code>.</td></tr> -<tr valign="top"> <td><code>memory</code></td> - <td> </td> - <td>Defines the allocator to be used for allocating bookkeeping - information.</td></tr> <tr valign="top"> <td><code>ppte</code></td> <td> </td> <td>The implementation should return a pointer to its state @@ -3001,12 +2745,26 @@ follows:</dd> <p> <code>text_begin</code> must allocate a structure for its bookkeeping -needs, using the allocator defined by the <code>memory</code> parameter, +needs, using the allocator used by the graphics state, and return it in <code>*ppte</code>. <code>text_begin</code> may assume that the structures passed as parameters will survive until text processing is complete.</p> <p> +If the text operation includes <code>TEXT_DO...PATH</code> then the +character outline will be appended to the current path in the +<code>pgs</code>. The current point of that path indicates where +drawing should occur and will be updated by the string width +(unless the text operation includes <code>TEXT_DO_NONE</code>).</p> + +<p>If the text operation includes <code>TEXT_DO_DRAW</code> then +the text color will be taken from the current colour in the graphics +state. (Otherwise no colour is required).</p> + +<p>The bookkeeping information will be allocated using the memory +allocator from the graphics state.</p> + +<p> Clients should not call the driver <code>text_begin</code> procedure directly. Instead, they should call <code>gx_device_text_begin</code>, which takes the same parameters and also initializes certain common elements @@ -3093,8 +2851,7 @@ if the glyph can't be translated to Unicode.</p> <dl> <dt><code>int (*get_bits_rectangle)(gx_device *dev, -const gs_int_rect *prect, gs_get_bits_params_t *params, -gs_int_rect **unread)</code> <b><em>[OPTIONAL]</em></b></dt> +const gs_int_rect *prect, gs_get_bits_params_t *params)</code> <b><em>[OPTIONAL]</em></b></dt> <p><dd> Read a rectangle of bits back from the device. The <code>params</code> @@ -3209,49 +2966,6 @@ in each scan line are undefined. If the implementation returns pointers to the data, it stores them into <code>data[0]</code> or <code>data[</code><b><em>0..N-1</em></b><code>]</code>.</p> -<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 <code>NULL</code>. If unread is -<code>NULL</code>, return <code>gs_error_ioerror</code>; in this case, -some bits may or may not have been read. If unread is not -<code>NULL</code>, allocate (using <code>dev</code>->memory) and -fill in a list of rectangles that could not be read, store the pointer to -the list in <code>*unread</code>, 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.</p> -</dl> - -<dl> -<dt><code>int (*get_bits)(gx_device *dev, int y, -byte *data, byte **actual_data)</code> -<b><em>[OPTIONAL]</em></b></dt> -<dd>Read scan line <code>y</code> of bits back from the device into the -area starting at data. This call is functionally equivalent to</dd> - -<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 -<code>params</code>-><code>data[0]</code> stored in -<code>*actual_data</code>, and will in fact be implemented this way if -the device defines a <code>get_bits_rectangle</code> procedure and does -not define one for <code>get_bits</code>. (If -<code>actual_data</code> is <code>NULL</code>, -<code>GB_RETURN_POINTER</code> is omitted from the options.)</p> -</dl> - <h3><a name="Parameters"></a>Parameters</h3> <p> @@ -3402,32 +3116,6 @@ processed and stored. </dd> </dl></blockquote> -<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:</p> - -<dl> -<dt><code>xfont_procs *(*get_xfont_procs)(gx_device *dev)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Return a structure of procedures for handling external fonts and text -display. A <code>NULL</code> value means that this driver doesn't -provide this capability.</dd> -</dl> - -<p> -For technical reasons, a second procedure is also needed:</p> - -<dl> -<dt><code>gx_device *(*get_xfont_device)(gx_device *dev)</code> <b><em>[OPTIONAL]</em></b></dt> -<dd>Return the device that implements <code>get_xfont_procs</code> in a -non-default way for this device, if any. Except for certain special -internal devices, this is always the device argument.</dd> -</dl> - <h3><a name="Page_devices"></a>Page devices</h3> <dl> @@ -3684,7 +3372,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. <p> -<small>Ghostscript version 9.54.0, 30 March 2021 +<small>Ghostscript version 9.55.0, 27 September 2021 <!-- [3.0 end visible trailer] ============================================= --> |