xref: /plan9/sys/src/cmd/gs/doc/Drivers.htm (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
13ff48bf5SDavid du Colombier<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
27dd7cddfSDavid du Colombier<html>
37dd7cddfSDavid du Colombier<head>
47dd7cddfSDavid du Colombier<title>The interface between Ghostscript and device drivers</title>
5*593dc095SDavid du Colombier<!-- $Id: Drivers.htm,v 1.58 2005/10/20 19:46:23 ray Exp $ -->
67dd7cddfSDavid du Colombier<!-- Originally: drivers.txt -->
73ff48bf5SDavid du Colombier<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style">
87dd7cddfSDavid du Colombier</head>
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier<body>
117dd7cddfSDavid du Colombier<!-- [1.0 begin visible header] ============================================ -->
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier<!-- [1.1 begin headline] ================================================== -->
147dd7cddfSDavid du Colombier
153ff48bf5SDavid du Colombier<h1>The interface between Ghostscript and device drivers</h1>
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier<!-- [1.1 end headline] ==================================================== -->
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier<!-- [1.2 begin table of contents] ========================================= -->
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier<h2>Table of contents</h2>
227dd7cddfSDavid du Colombier
237dd7cddfSDavid du Colombier<blockquote><ul>
247dd7cddfSDavid du Colombier<li><a href="#Adding_drivers">Adding a driver</a>
257dd7cddfSDavid du Colombier<li><a href="#KISS">Keeping things simple</a>
267dd7cddfSDavid du Colombier<li><a href="#Structure">Driver structure</a>
277dd7cddfSDavid du Colombier<ul>
287dd7cddfSDavid du Colombier<li><a href="#Structure_definition">Structure definition</a>
297dd7cddfSDavid du Colombier<li><a href="#Sophisticated">For sophisticated developers only</a>
307dd7cddfSDavid du Colombier</ul>
317dd7cddfSDavid du Colombier<li><a href="#coordinates_and_types">Coordinates and types</a>
327dd7cddfSDavid du Colombier<ul>
337dd7cddfSDavid du Colombier<li><a href="#Coordinate_system">Coordinate system</a>
347dd7cddfSDavid du Colombier<li><a href="#Color_definition">Color definition</a>
35*593dc095SDavid du Colombier<ul>
36*593dc095SDavid du Colombier<li><a href="#sep_and_linear_fields">Separable and linear fields</a>
37*593dc095SDavid du Colombier<li><a href="#Changing_color_info_data">Changing color_info data</a>
38*593dc095SDavid du Colombier</ul>
397dd7cddfSDavid du Colombier<li><a href="#Types">Types</a>
407dd7cddfSDavid du Colombier</ul>
417dd7cddfSDavid du Colombier<li><a href="#Coding_conventions">Coding conventions</a>
427dd7cddfSDavid du Colombier<ul>
437dd7cddfSDavid du Colombier<li><a href="#Allocating_storage">Allocating storage</a>
447dd7cddfSDavid du Colombier<li><a href="#Driver_instance_allocation">Driver instance allocation</a>
457dd7cddfSDavid du Colombier</ul>
467dd7cddfSDavid du Colombier<li><a href="#Printer_drivers">Printer drivers</a>
477dd7cddfSDavid du Colombier<li><a href="#Driver_procedures">Driver procedures</a>
487dd7cddfSDavid du Colombier<ul>
497dd7cddfSDavid du Colombier<li><a href="#Life_cycle">Life cycle</a>
503ff48bf5SDavid du Colombier<li><a href="#Open_close">Open, close, sync, copy</a>
517dd7cddfSDavid du Colombier<li><a href="#Color_mapping">Color and alpha mapping</a>
527dd7cddfSDavid du Colombier<li><a href="#Pixel_level_drawing">Pixel-level drawing</a>
537dd7cddfSDavid du Colombier<ul>
547dd7cddfSDavid du Colombier<li><a href="#Bitmap_imaging">Bitmap imaging</a>
557dd7cddfSDavid du Colombier<li><a href="#Pixmap_imaging">Pixmap imaging</a>
567dd7cddfSDavid du Colombier<li><a href="#Compositing">Compositing</a>
577dd7cddfSDavid du Colombier  [<a href="#S_spec">S</a>, <a href="#T_spec">T</a>, <a href="#F_spec">f</a>,
587dd7cddfSDavid du Colombier   <a href="#Compositing_notes">Notes</a>]
597dd7cddfSDavid du Colombier</ul>
607dd7cddfSDavid du Colombier<li><a href="#Polygon_level_drawing">Polygon-level drawing</a>
61*593dc095SDavid du Colombier<li><a href="#Linear_color_drawing">Linear color drawing</a>
627dd7cddfSDavid du Colombier<li><a href="#High_level_drawing">High-level drawing</a>
637dd7cddfSDavid du Colombier<ul>
647dd7cddfSDavid du Colombier<li><a href="#Paths">Paths</a>
657dd7cddfSDavid du Colombier<li><a href="#Images">Images</a> [<a href="#Images_notes">Notes</a>]
663ff48bf5SDavid du Colombier<li><a href="#Text">Text</a> [<a href="#Text_notes">Notes</a>]
67*593dc095SDavid du Colombier<li><a href="#Unicode">Unicode support for high level devices</a>
687dd7cddfSDavid du Colombier</ul>
697dd7cddfSDavid du Colombier<li><a href="#Reading_bits_back">Reading bits back</a>
707dd7cddfSDavid du Colombier<li><a href="#Parameters">Parameters</a>
717dd7cddfSDavid du Colombier<ul>
727dd7cddfSDavid du Colombier<li><a href="#Default_CRD_parameters">Default color rendering dictionary (CRD) parameters</a>
737dd7cddfSDavid du Colombier</ul>
747dd7cddfSDavid du Colombier<li><a href="#External_fonts">External fonts</a>
757dd7cddfSDavid du Colombier<li><a href="#Page_devices">Page devices</a>
767dd7cddfSDavid du Colombier<li><a href="#Miscellaneous">Miscellaneous</a>
777dd7cddfSDavid du Colombier</ul>
787dd7cddfSDavid du Colombier</ul></blockquote>
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier<!-- [1.2 end table of contents] =========================================== -->
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier<!-- [1.3 begin hint] ====================================================== -->
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier<p>For other information, see the <a href="Readme.htm">Ghostscript
857dd7cddfSDavid du Colombieroverview</a> and the documentation on <a href="Make.htm">how to build
867dd7cddfSDavid du ColombierGhostscript</a>.
877dd7cddfSDavid du Colombier
887dd7cddfSDavid du Colombier<!-- [1.3 end hint] ======================================================== -->
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier<hr>
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier<!-- [1.0 end visible header] ============================================== -->
937dd7cddfSDavid du Colombier
947dd7cddfSDavid du Colombier<!-- [2.0 begin contents] ================================================== -->
957dd7cddfSDavid du Colombier
963ff48bf5SDavid du Colombier<h2><a name="Adding_drivers"></a>Adding a driver</h2>
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier<p>
997dd7cddfSDavid du ColombierTo add a driver to Ghostscript, first pick a name for your device, say
1007dd7cddfSDavid du Colombier"<b><tt>smurf</tt></b>".  (Device names must be 1 to 8 characters, begin
1017dd7cddfSDavid du Colombierwith a letter, and consist only of letters, digits, and underscores.  Case
1027dd7cddfSDavid du Colombieris significant: all current device names are lower case.)  Then all you
1037dd7cddfSDavid du Colombierneed do is edit <b><tt>contrib.mak</tt></b> in two places.
1047dd7cddfSDavid du Colombier
1057dd7cddfSDavid du Colombier<ol>
1067dd7cddfSDavid du Colombier<li>The list of devices, in the section headed "Catalog".  Add
1077dd7cddfSDavid du Colombier<b><tt>smurf</tt></b> to the list.
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier<li>The section headed "Device drivers".
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier<p>
1127dd7cddfSDavid du ColombierSuppose the files containing the smurf driver are called
1137dd7cddfSDavid du Colombier"<b><tt>joe</tt></b>" and "<b><tt>fred</tt></b>".  Then you should add the
1147dd7cddfSDavid du Colombierfollowing lines:
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier<blockquote>
1177dd7cddfSDavid du Colombier<pre># ------ The SMURF device ------ #
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombiersmurf_=$(GLOBJ)joe.$(OBJ) $(GLOBJ)fred.$(OBJ)
1207dd7cddfSDavid du Colombier$(DD)smurf.dev: $(smurf_)
1217dd7cddfSDavid du Colombier        $(SETDEV) $(DD)smurf $(smurf_)
1227dd7cddfSDavid du Colombier
1237dd7cddfSDavid du Colombier$(GLOBJ)joe.$(OBJ) : $(GLSRC)joe.c
1247dd7cddfSDavid du Colombier	$(GLCC) $(GLO_)joe.$(OBJ) $(C_) $(GLSRC)joe.c
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier$(GLOBJ)fred.$(OBJ) : $(GLSRC)fred.c
1277dd7cddfSDavid du Colombier	$(GLCC) $(GLO_)fred.$(OBJ) $(C_) $(GLSRC)fred.c</pre>
1287dd7cddfSDavid du Colombier</blockquote>
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier<p>
1317dd7cddfSDavid du Colombierand whatever <b><tt>joe.c</tt></b> and <b><tt>fred.c</tt></b> depend on.
1327dd7cddfSDavid du ColombierIf the smurf driver also needs special libraries, for instance a library
1337dd7cddfSDavid du Colombiernamed "<b><tt>gorf</tt></b>", then the entry should look like this:
1347dd7cddfSDavid du Colombier
1357dd7cddfSDavid du Colombier<blockquote>
1367dd7cddfSDavid du Colombier<pre>$(DD)smurf.dev : $(smurf_)
1377dd7cddfSDavid du Colombier        $(SETDEV) $(DD)smurf $(smurf_)
1387dd7cddfSDavid du Colombier        $(ADDMOD) $(DD)smurf -lib gorf</pre>
1397dd7cddfSDavid du Colombier</blockquote>
1407dd7cddfSDavid du Colombier
1417dd7cddfSDavid du Colombier<p>
1427dd7cddfSDavid du ColombierIf, as will usually be the case, your driver is a printer driver (as
1437dd7cddfSDavid du Colombier<a href="#Printer_drivers">discussed below</a>), the device entry should
1447dd7cddfSDavid du Colombierlook like this:
1457dd7cddfSDavid du Colombier
1467dd7cddfSDavid du Colombier<blockquote>
1477dd7cddfSDavid du Colombier<pre>$(DD)smurf.dev : $(smurf_) $(GLD)page.dev
1487dd7cddfSDavid du Colombier        $(SETPDEV) $(DD)smurf $(smurf_)</pre>
1497dd7cddfSDavid du Colombier</blockquote>
1507dd7cddfSDavid du Colombier
1517dd7cddfSDavid du Colombier<p>
1527dd7cddfSDavid du Colombieror
1537dd7cddfSDavid du Colombier
1547dd7cddfSDavid du Colombier<blockquote>
1557dd7cddfSDavid du Colombier<pre>$(DD)smurf.dev : $(smurf_) $(GLD)page.dev
1567dd7cddfSDavid du Colombier        $(SETPDEV) $(DD)smurf $(smurf_)
1577dd7cddfSDavid du Colombier        $(ADDMOD) $(DD)smurf -lib gorf</pre>
1587dd7cddfSDavid du Colombier</blockquote>
1597dd7cddfSDavid du Colombier
1607dd7cddfSDavid du Colombier<p>
1617dd7cddfSDavid du ColombierNote that the space before the :, and the explicit compilation rules for the
1627dd7cddfSDavid du Colombier.c files, are required for portability,
1637dd7cddfSDavid du Colombier</ol>
1647dd7cddfSDavid du Colombier
1657dd7cddfSDavid du Colombier<hr>
1667dd7cddfSDavid du Colombier
1673ff48bf5SDavid du Colombier<h2><a name="KISS"></a>Keeping things simple</h2>
1687dd7cddfSDavid du Colombier
1697dd7cddfSDavid du Colombier<p>
1703ff48bf5SDavid du ColombierIf you want to add a simple device (specifically, a monochrome printer), you
1713ff48bf5SDavid du Colombierprobably don't need to read the rest of this document; just use the code in
1723ff48bf5SDavid du Colombieran existing driver as a guide.  The Epson and Canon BubbleJet drivers <a
1733ff48bf5SDavid du Colombierhref="../src/gdevepsn.c">gdevepsn.c</a> and <a
1743ff48bf5SDavid du Colombierhref="../src/gdevbj10.c">gdevbj10.c</a> are good models for dot-matrix
1753ff48bf5SDavid du Colombierprinters, which require presenting the data for many scan lines at once; the
1763ff48bf5SDavid du ColombierDeskJet/LaserJet drivers in <a href="../src/gdevdjet.c">gdevdjet.c</a> are
1773ff48bf5SDavid du Colombiergood models for laser printers, which take a single scan line at a time but
1783ff48bf5SDavid du Colombiersupport data compression.  For color printers, there are unfortunately no
1793ff48bf5SDavid du Colombiergood models: the two major color inkjet printer drivers, <a
1803ff48bf5SDavid du Colombierhref="../src/gdevcdj.c">gdevcdj.c</a> and <a
1813ff48bf5SDavid du Colombierhref="../src/gdevstc.c">gdevstc.c</a>, are far too complex to read.
1827dd7cddfSDavid du Colombier
1837dd7cddfSDavid du Colombier<p>
1847dd7cddfSDavid du ColombierOn the other hand, if you're writing a driver for some more esoteric
1857dd7cddfSDavid du Colombierdevice, you probably do need at least some of the information in the rest
1867dd7cddfSDavid du Colombierof this document.  It might be a good idea for you to read it in
1877dd7cddfSDavid du Colombierconjunction with one of the existing drivers.
1887dd7cddfSDavid du Colombier
1897dd7cddfSDavid du Colombier<p>
1907dd7cddfSDavid du ColombierDuplication of code, and sheer volume of code, is a serious maintenance and
1917dd7cddfSDavid du Colombierdistribution problem for Ghostscript.  If your device is similar to an
1927dd7cddfSDavid du Colombierexisting one, try to implement your driver by adding some parameterization
1937dd7cddfSDavid du Colombierto an existing driver rather than by copying code to create an entirely new
1943ff48bf5SDavid du Colombiersource module.  <a href="../src/gdevepsn.c">gdevepsn.c</a> and <a
1953ff48bf5SDavid du Colombierhref="../src/gdevdjet.c">gdevdjet.c</a> are good examples of this approach.
1967dd7cddfSDavid du Colombier
1977dd7cddfSDavid du Colombier<hr>
1987dd7cddfSDavid du Colombier
1993ff48bf5SDavid du Colombier<h2><a name="Structure"></a>Driver structure</h2>
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier<p>
2027dd7cddfSDavid du ColombierA device is represented by a structure divided into three parts:
2037dd7cddfSDavid du Colombier
2047dd7cddfSDavid du Colombier<ul>
2057dd7cddfSDavid du Colombier<li>procedures that are (normally) shared by all instances of each device;
2067dd7cddfSDavid du Colombier
2077dd7cddfSDavid du Colombier<li>parameters that are present in all devices but may be different for
2087dd7cddfSDavid du Colombiereach device or instance; and
2097dd7cddfSDavid du Colombier
2107dd7cddfSDavid du Colombier<li>device-specific parameters that may be different for each instance.
2117dd7cddfSDavid du Colombier</ul>
2127dd7cddfSDavid du Colombier
2137dd7cddfSDavid du Colombier<p>
2147dd7cddfSDavid du ColombierNormally the procedure structure is defined and initialized at compile
2157dd7cddfSDavid du Colombiertime.  A prototype of the parameter structure (including both generic and
2167dd7cddfSDavid du Colombierdevice-specific parameters) is defined and initialized at compile time, but
2177dd7cddfSDavid du Colombieris copied and filled in when an instance of the device is created.  Both of
2187dd7cddfSDavid du Colombierthese structures should be declared as <b><tt>const</tt></b>, but for backward
2197dd7cddfSDavid du Colombiercompatibility reasons the latter is not.
2207dd7cddfSDavid du Colombier
2217dd7cddfSDavid du Colombier<p>
2227dd7cddfSDavid du ColombierThe <b><tt>gx_device_common</tt></b> macro defines the common structure
2237dd7cddfSDavid du Colombierelements, with the intent that devices define and export a structure along
2243ff48bf5SDavid du Colombierthe following lines.  Do not fill in the individual generic parameter values
2253ff48bf5SDavid du Colombierin the usual way for C structures: use the macros defined for this purpose
2263ff48bf5SDavid du Colombierin <a href="../src/gxdevice.h">gxdevice.h</a> or, if applicable, <a
2273ff48bf5SDavid du Colombierhref="../src/gdevprn.h">gdevprn.h</a>.
2287dd7cddfSDavid du Colombier
2297dd7cddfSDavid du Colombier<blockquote>
2307dd7cddfSDavid du Colombier<pre>typedef struct smurf_device_s {
2317dd7cddfSDavid du Colombier        gx_device_common;
2327dd7cddfSDavid du Colombier        <b><em>... device-specific parameters ...</em></b>
2337dd7cddfSDavid du Colombier} smurf_device;
2347dd7cddfSDavid du Colombiersmurf_device gs_smurf_device = {
2357dd7cddfSDavid du Colombier        <b><em>... macro for generic parameter values ...,</em></b>
2367dd7cddfSDavid du Colombier        { <b><em>... procedures ...</em></b> },         /* std_procs */
2377dd7cddfSDavid du Colombier        <b><em>... device-specific parameter values if any ...</em></b>
2387dd7cddfSDavid du Colombier};</pre>
2397dd7cddfSDavid du Colombier</blockquote>
2407dd7cddfSDavid du Colombier<p>
2417dd7cddfSDavid du ColombierThe device structure instance <b>must</b> have the name
2427dd7cddfSDavid du Colombier<b><tt>gs_smurf_device</tt></b>, where <b><tt>smurf</tt></b> is the device
2437dd7cddfSDavid du Colombiername used in <b><tt>contrib.mak</tt></b>.  <b><tt>gx_device_common</tt></b>
2447dd7cddfSDavid du Colombieris a macro consisting only of the element definitions.
2457dd7cddfSDavid du Colombier<p>
2467dd7cddfSDavid du ColombierAll the device procedures are called with the device as the first argument.
2477dd7cddfSDavid du ColombierSince each device type is actually a different structure type, the device
2487dd7cddfSDavid du Colombierprocedures must be declared as taking a <b><tt>gx_device&nbsp;*</tt></b> as
2497dd7cddfSDavid du Colombiertheir first argument, and must cast it to
2507dd7cddfSDavid du Colombier<b><tt>smurf_device&nbsp;*</tt></b> internally.  For example, in the code
2517dd7cddfSDavid du Colombierfor the "memory" device, the first argument to all routines is called
2527dd7cddfSDavid du Colombier<b><tt>dev</tt></b>, but the routines actually use <b><tt>mdev</tt></b> to
2537dd7cddfSDavid du Colombierrefer to elements of the full structure, using the following standard
2547dd7cddfSDavid du Colombierinitialization statement at the beginning of each procedure:
2557dd7cddfSDavid du Colombier
2567dd7cddfSDavid du Colombier<blockquote>
2577dd7cddfSDavid du Colombier<pre>gx_memory_device *const mdev = (gx_device_memory *)dev;</pre>
2587dd7cddfSDavid du Colombier</blockquote>
2597dd7cddfSDavid du Colombier
2607dd7cddfSDavid du Colombier<p>
2617dd7cddfSDavid du Colombier(This is a cheap version of "object-oriented" programming: in C++, for
2627dd7cddfSDavid du Colombierexample, the cast would be unnecessary, and in fact the procedure table
2637dd7cddfSDavid du Colombierwould be constructed by the compiler.)
2647dd7cddfSDavid du Colombier
2653ff48bf5SDavid du Colombier<h3><a name="Structure_definition"></a>Structure definition</h3>
2667dd7cddfSDavid du Colombier
2677dd7cddfSDavid du Colombier<p>
2687dd7cddfSDavid du ColombierYou should consult the definition of struct <b><tt>gx_device_s</tt></b> in
2693ff48bf5SDavid du Colombier<a href="../src/gxdevice.h">gxdevice.h</a> for the complete details of the
2703ff48bf5SDavid du Colombiergeneric device structure.  Some of the most important members of this
2713ff48bf5SDavid du Colombierstructure for ordinary drivers are:
2727dd7cddfSDavid du Colombier
2737dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
2747dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>const char *dname;</tt></b>
2757dd7cddfSDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;&nbsp;
2767dd7cddfSDavid du Colombier	<td>The device name
2777dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>bool is_open;</tt></b>
2787dd7cddfSDavid du Colombier	<td>&nbsp;
2797dd7cddfSDavid du Colombier	<td>True if device has been opened
2807dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>gx_device_color_info color_info;</tt></b>
2817dd7cddfSDavid du Colombier	<td>&nbsp;
2827dd7cddfSDavid du Colombier	<td>Color information
2837dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>int width;</tt></b>
2847dd7cddfSDavid du Colombier	<td>&nbsp;
2857dd7cddfSDavid du Colombier	<td>Width in pixels
2867dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>int height;</tt></b>
2877dd7cddfSDavid du Colombier	<td>&nbsp;
2887dd7cddfSDavid du Colombier	<td>Height in pixels
2897dd7cddfSDavid du Colombier</table></blockquote>
2907dd7cddfSDavid du Colombier
2917dd7cddfSDavid du Colombier<p>
2927dd7cddfSDavid du ColombierThe name in the structure (<b><tt>dname</tt></b>) should be the same as the
2933ff48bf5SDavid du Colombiername in <a href="../src/contrib.mak">contrib.mak</a>.
2947dd7cddfSDavid du Colombier
2953ff48bf5SDavid du Colombier<h3><a name="Sophisticated"></a>For sophisticated developers only</h3>
2967dd7cddfSDavid du Colombier
2977dd7cddfSDavid du Colombier<p>
2987dd7cddfSDavid du ColombierIf for any reason you need to change the definition of the basic device
2997dd7cddfSDavid du Colombierstructure, or to add procedures, you must change the following places:
3007dd7cddfSDavid du Colombier
3017dd7cddfSDavid du Colombier<blockquote><ul>
3027dd7cddfSDavid du Colombier<li>This document and the <a href="News.htm">news document</a> (if you want
3037dd7cddfSDavid du Colombier	to keep the documentation up to date).
3047dd7cddfSDavid du Colombier<li>The definition of <b><tt>gx_device_common</tt></b> and the procedures
3053ff48bf5SDavid du Colombier	in <a href="../src/gxdevcli.h">gxdevcli.h</a>.
3067dd7cddfSDavid du Colombier<li>Possibly, the default forwarding procedures declared in
3073ff48bf5SDavid du Colombier	<a href="../src/gxdevice.h">gxdevice.h</a> and implemented in
3083ff48bf5SDavid du Colombier	<a href="../src/gdevnfwd.c">gdevnfwd.c</a>.
3097dd7cddfSDavid du Colombier<li>The device procedure record completion routines in
3103ff48bf5SDavid du Colombier	<a href="../src/gdevdflt.c">gdevdflt.c</a>.
3117dd7cddfSDavid du Colombier<li>Possibly, the default device implementation in
3123ff48bf5SDavid du Colombier	<a href="../src/gdevdflt.c">gdevdflt.c</a>,
3133ff48bf5SDavid du Colombier	<a href="../src/gdevddrw.c">gdevddrw.c</a>, and
3143ff48bf5SDavid du Colombier	<a href="../src/gxcmap.c">gxcmap.c</a>.
3153ff48bf5SDavid du Colombier<li>The bounding box device in <a href="../src/gdevbbox.c">gdevbbox.c</a>
3163ff48bf5SDavid du Colombier	(probably just adding <b><tt>NULL</tt></b> procedure entries if the
3173ff48bf5SDavid du Colombier	new procedures don't produce output).
3187dd7cddfSDavid du Colombier<li>These devices that must have complete (non-defaulted) procedure vectors:
3197dd7cddfSDavid du Colombier<ul>
3203ff48bf5SDavid du Colombier<li>The null device in <a href="../src/gdevnfwd.c">gdevnfwd.c</a>.
3213ff48bf5SDavid du Colombier<li>The command list "device" in <a href="../src/gxclist.c">gxclist.c</a>.
3223ff48bf5SDavid du Colombier	This is not an actual device; it only defines procedures.
3233ff48bf5SDavid du Colombier<li>The "memory" devices in <a href="../src/gdevmem.h">gdevmem.h</a> and
3247dd7cddfSDavid du Colombier	<b><tt>gdevm*.c</tt></b>.
3257dd7cddfSDavid du Colombier</ul>
3263ff48bf5SDavid du Colombier<li>The clip list accumulation "device" in
3273ff48bf5SDavid du Colombier	<a href="../src/gxacpath.c">gxacpath.c</a>.
3283ff48bf5SDavid du Colombier<li>The clipping "devices" <a href="../src/gxclip.c">gxclip.c</a>,
3293ff48bf5SDavid du Colombier	<a href="../src/gxclip2.c">gxclip2.c</a>,
3303ff48bf5SDavid du Colombier	and <a href="../src/gxclipm.c">gxclipm.c</a>.
3313ff48bf5SDavid du Colombier<li>The pattern accumulation "device" in
3323ff48bf5SDavid du Colombier	<a href="../src/gxpcmap.c">gxpcmap.c</a>.
3333ff48bf5SDavid du Colombier<li>The hit detection "device" in <a href="../src/gdevhit.c">gdevhit.c</a>.
3343ff48bf5SDavid du Colombier<li>The generic printer device macros in
3353ff48bf5SDavid du Colombier	<a href="../src/gdevprn.h">gdevprn.h</a>.
3363ff48bf5SDavid du Colombier<li>The generic printer device code in
3373ff48bf5SDavid du Colombier	<a href="../src/gdevprn.c">gdevprn.c</a>.
3383ff48bf5SDavid du Colombier<li>The RasterOp source device in
3393ff48bf5SDavid du Colombier	<a href="../src/gdevrops.c">gdevrops.c</a>.
3407dd7cddfSDavid du Colombier</ul></blockquote>
3417dd7cddfSDavid du Colombier
3427dd7cddfSDavid du Colombier<p>
3437dd7cddfSDavid du ColombierYou may also have to change the code for
3447dd7cddfSDavid du Colombier<b><tt>gx_default_get_params</tt></b> or
3453ff48bf5SDavid du Colombier<b><tt>gx_default_put_params</tt></b> in <a
3463ff48bf5SDavid du Colombierhref="../src/gsdparam.c">gsdparam.c</a>.
3477dd7cddfSDavid du Colombier
3487dd7cddfSDavid du Colombier<p>
3497dd7cddfSDavid du ColombierYou should not have to change any of the real devices in the standard
3503ff48bf5SDavid du ColombierGhostscript distribution (listed in <a href="../src/devs.mak">devs.mak</a>
3513ff48bf5SDavid du Colombierand <a href="../src/contrib.mak">contrib.mak</a>) or any of your own
3523ff48bf5SDavid du Colombierdevices, because all of them are supposed to use the macros in <a
3533ff48bf5SDavid du Colombierhref="../src/gxdevice.h">gxdevice.h</a> or <a
3543ff48bf5SDavid du Colombierhref="../src/gdevprn.h">gdevprn.h</a> to define and initialize their state.
3557dd7cddfSDavid du Colombier
3567dd7cddfSDavid du Colombier<hr>
3577dd7cddfSDavid du Colombier
3583ff48bf5SDavid du Colombier<h2><a name="coordinates_and_types"></a>Coordinates and types</h2>
3597dd7cddfSDavid du Colombier
3603ff48bf5SDavid du Colombier<h3><a name="Coordinate_system"></a>Coordinate system</h3>
3617dd7cddfSDavid du Colombier
3627dd7cddfSDavid du Colombier<p>
3637dd7cddfSDavid du ColombierSince each driver specifies the initial transformation from user
3647dd7cddfSDavid du Colombiercoordinates to device coordinates, the driver can use any coordinate system
3657dd7cddfSDavid du Colombierit wants, as long as a device coordinate will fit in an
3667dd7cddfSDavid du Colombier<b><tt>int</tt></b>.  (This is only an issue on DOS systems, where ints are
3677dd7cddfSDavid du Colombieronly 16 bits.  User coordinates are represented as floats.)  Most current
3687dd7cddfSDavid du Colombierdrivers use a coordinate system with (0,0) in the upper left corner, with
3697dd7cddfSDavid du Colombier<b><em>X</em></b> increasing to the right and <b><em>Y</em></b> increasing
3707dd7cddfSDavid du Colombiertoward the bottom.  However, there is supposed to be nothing in the rest of
3717dd7cddfSDavid du ColombierGhostscript that assumes this, and indeed some drivers use a coordinate
3727dd7cddfSDavid du Colombiersystem with (0,0) in the lower left corner.
3737dd7cddfSDavid du Colombier
3747dd7cddfSDavid du Colombier<p>
3753ff48bf5SDavid du ColombierDrivers must check (and, if necessary, clip) the coordinate parameters given
3763ff48bf5SDavid du Colombierto them: they should not assume the coordinates will be in bounds.  The
3773ff48bf5SDavid du Colombier<b><tt>fit_fill</tt></b> and <b><tt>fit_copy</tt></b> macros in <a
3783ff48bf5SDavid du Colombierhref="../src/gxdevice.h">gxdevice.h</a> are very helpful in doing this.
3797dd7cddfSDavid du Colombier
3803ff48bf5SDavid du Colombier<h3><a name="Color_definition"></a>Color definition</h3>
3817dd7cddfSDavid du Colombier
3827dd7cddfSDavid du Colombier<p>
383*593dc095SDavid du ColombierBetween the Ghostscript graphics library and the device, colors are
384*593dc095SDavid du Colombierrepresented in three forms. Color components in a color space (Gray, RGB,
385*593dc095SDavid du ColombierDeviceN, etc.) represented as <b><tt>frac</tt></b> values. Device colorants
386*593dc095SDavid du Colombierare represented as <b><tt>gx_color_value</tt></b> values.  For many
387*593dc095SDavid du Colombierprocedures, colors are represented in a type called
388*593dc095SDavid du Colombier<b><tt>gx_color_index</tt></b>.
389*593dc095SDavid du ColombierAll three types are described in more detail in <a href="#Types">Types</a>
3907dd7cddfSDavid du Colombier
3917dd7cddfSDavid du Colombier<p>
3927dd7cddfSDavid du ColombierThe <b><tt>color_info</tt></b> member of the device structure defines the
3937dd7cddfSDavid du Colombiercolor and gray-scale capabilities of the device.  Its type is defined as
3947dd7cddfSDavid du Colombierfollows:
3957dd7cddfSDavid du Colombier
3967dd7cddfSDavid du Colombier<blockquote>
397*593dc095SDavid du Colombier<pre>
398*593dc095SDavid du Colombier/*
399*593dc095SDavid du Colombier * The enlarged color model information structure: Some of the
400*593dc095SDavid du Colombier * information that was implicit in the component number in
401*593dc095SDavid du Colombier * the earlier conventions (component names, polarity, mapping
402*593dc095SDavid du Colombier * functions) are now explicitly provided.
403*593dc095SDavid du Colombier *
404*593dc095SDavid du Colombier * Also included is some information regarding the encoding of
405*593dc095SDavid du Colombier * color information into gx_color_index. Some of this information
406*593dc095SDavid du Colombier * was previously gathered indirectly from the mapping
407*593dc095SDavid du Colombier * functions in the existing code, specifically to speed up the
408*593dc095SDavid du Colombier * halftoned color rendering operator (see
409*593dc095SDavid du Colombier * gx_dc_ht_colored_fill_rectangle in gxcht.c). The information
410*593dc095SDavid du Colombier * is now provided explicitly because such optimizations are
411*593dc095SDavid du Colombier * more critical when the number of color components is large.
412*593dc095SDavid du Colombier *
413*593dc095SDavid du Colombier * Note: no pointers have been added to this structure, so there
414*593dc095SDavid du Colombier *       is no requirement for a structure descriptor.
415*593dc095SDavid du Colombier */
416*593dc095SDavid du Colombiertypedef struct gx_device_color_info_s {
417*593dc095SDavid du Colombier
418*593dc095SDavid du Colombier    /*
419*593dc095SDavid du Colombier     * max_components is the maximum number of components for all
420*593dc095SDavid du Colombier     * color models supported by this device. This does not include
421*593dc095SDavid du Colombier     * any alpha components.
422*593dc095SDavid du Colombier     */
423*593dc095SDavid du Colombier    int max_components;
424*593dc095SDavid du Colombier
425*593dc095SDavid du Colombier    /*
426*593dc095SDavid du Colombier     * The number of color components. This does not include any
427*593dc095SDavid du Colombier     * alpha-channel information, which may be integrated into
428*593dc095SDavid du Colombier     * the gx_color_index but is otherwise passed as a separate
429*593dc095SDavid du Colombier     * component.
430*593dc095SDavid du Colombier     */
431*593dc095SDavid du Colombier    int num_components;
432*593dc095SDavid du Colombier
433*593dc095SDavid du Colombier    /*
434*593dc095SDavid du Colombier     * Polarity of the components of the color space, either
435*593dc095SDavid du Colombier     * additive or subtractive. This is used to interpret transfer
436*593dc095SDavid du Colombier     * functions and halftone threshold arrays. Possible values
437*593dc095SDavid du Colombier     * are GX_CM_POLARITY_ADDITIVE or GX_CM_POLARITY_SUBTRACTIVE
438*593dc095SDavid du Colombier     */
439*593dc095SDavid du Colombier    gx_color_polarity_t polarity;
440*593dc095SDavid du Colombier
441*593dc095SDavid du Colombier    /*
442*593dc095SDavid du Colombier     * The number of bits of gx_color_index actually used.
443*593dc095SDavid du Colombier     * This must be <= sizeof(gx_color_index), which is usually 64.
444*593dc095SDavid du Colombier     */
445*593dc095SDavid du Colombier    byte depth;
446*593dc095SDavid du Colombier
447*593dc095SDavid du Colombier    /*
448*593dc095SDavid du Colombier     * Index of the gray color component, if any. The max_gray and
449*593dc095SDavid du Colombier     * dither_gray values apply to this component only; all other
450*593dc095SDavid du Colombier     * components use the max_color and dither_color values.
451*593dc095SDavid du Colombier     *
452*593dc095SDavid du Colombier     * This will be GX_CINFO_COMP_NO_INDEX if there is no gray
453*593dc095SDavid du Colombier     * component.
454*593dc095SDavid du Colombier     */
455*593dc095SDavid du Colombier    byte gray_index;
456*593dc095SDavid du Colombier
457*593dc095SDavid du Colombier    /*
458*593dc095SDavid du Colombier     * max_gray and max_color are the number of distinct native
459*593dc095SDavid du Colombier     * intensity levels, less 1, for the gray and all other color
460*593dc095SDavid du Colombier     * components, respectively. For nearly all current devices
461*593dc095SDavid du Colombier     * that support both gray and non-gray components, the two
462*593dc095SDavid du Colombier     * parameters have the same value.
463*593dc095SDavid du Colombier     *
464*593dc095SDavid du Colombier     * dither_grays and dither_colors are the number of intensity
465*593dc095SDavid du Colombier     * levels between which halftoning can occur, for the gray and
466*593dc095SDavid du Colombier     * all other color components, respectively. This is
467*593dc095SDavid du Colombier     * essentially redundant information: in all reasonable cases,
468*593dc095SDavid du Colombier     * dither_grays = max_gray + 1 and dither_colors = max_color + 1.
469*593dc095SDavid du Colombier     * These parameters are, however, extensively used in the
470*593dc095SDavid du Colombier     * current code, and thus have been retained.
471*593dc095SDavid du Colombier     *
472*593dc095SDavid du Colombier     * Note that the non-gray values may now be relevant even if
473*593dc095SDavid du Colombier     * num_components == 1. This simplifies the handling of devices
474*593dc095SDavid du Colombier     * with configurable color models which may be set for a single
475*593dc095SDavid du Colombier     * non-gray color model.
476*593dc095SDavid du Colombier     */
477*593dc095SDavid du Colombier    gx_color_value max_gray;	/* # of distinct color levels -1 */
478*593dc095SDavid du Colombier    gx_color_value max_color;
479*593dc095SDavid du Colombier
480*593dc095SDavid du Colombier    gx_color_value dither_grays;
481*593dc095SDavid du Colombier    gx_color_value dither_colors;
482*593dc095SDavid du Colombier
483*593dc095SDavid du Colombier    /*
484*593dc095SDavid du Colombier     * Information to control super-sampling of objects to support
485*593dc095SDavid du Colombier     * anti-aliasing.
486*593dc095SDavid du Colombier     */
487*593dc095SDavid du Colombier    gx_device_anti_alias_info anti_alias;
488*593dc095SDavid du Colombier
489*593dc095SDavid du Colombier    /*
490*593dc095SDavid du Colombier     * Flag to indicate if gx_color_index for this device may be divided
491*593dc095SDavid du Colombier     * into individual fields for each component. This is almost always
492*593dc095SDavid du Colombier     * the case for printers, and is the case for most modern displays
493*593dc095SDavid du Colombier     * as well. When this is the case, halftoning may be performed
494*593dc095SDavid du Colombier     * separately for each component, which greatly simplifies processing
495*593dc095SDavid du Colombier     * when the number of color components is large.
496*593dc095SDavid du Colombier     *
497*593dc095SDavid du Colombier     * If the gx_color_index is separable in this manner, the comp_shift
498*593dc095SDavid du Colombier     * array provides the location of the low-order bit for each
499*593dc095SDavid du Colombier     * component. This may be filled in by the client, but need not be.
500*593dc095SDavid du Colombier     * If it is not provided, it will be calculated based on the values
501*593dc095SDavid du Colombier     * in the max_gray and max_color fields as follows:
502*593dc095SDavid du Colombier     *
503*593dc095SDavid du Colombier     *     comp_shift[num_components - 1] = 0,
504*593dc095SDavid du Colombier     *     comp_shift[i] = comp_shift[i + 1]
505*593dc095SDavid du Colombier     *                      + ( i == gray_index ? ceil(log2(max_gray + 1))
506*593dc095SDavid du Colombier     *                                          : ceil(log2(max_color + 1)) )
507*593dc095SDavid du Colombier     *
508*593dc095SDavid du Colombier     * The comp_mask and comp_bits fields should be left empty by the client.
509*593dc095SDavid du Colombier     * They will be filled in during initialization using the following
510*593dc095SDavid du Colombier     * mechanism:
511*593dc095SDavid du Colombier     *
512*593dc095SDavid du Colombier     *     comp_bits[i] = ( i == gray_index ? ceil(log2(max_gray + 1))
513*593dc095SDavid du Colombier     *                                      : ceil(log2(max_color + 1)) )
514*593dc095SDavid du Colombier     *
515*593dc095SDavid du Colombier     *     comp_mask[i] = (((gx_color_index)1 << comp_bits[i]) - 1)
516*593dc095SDavid du Colombier     *                       << comp_shift[i]
517*593dc095SDavid du Colombier     *
518*593dc095SDavid du Colombier     * (For current devices, it is almost always the case that
519*593dc095SDavid du Colombier     * max_gray == max_color, if the color model contains both gray and
520*593dc095SDavid du Colombier     * non-gray components.)
521*593dc095SDavid du Colombier     *
522*593dc095SDavid du Colombier     * If separable_and_linear is not set, the data in the other fields
523*593dc095SDavid du Colombier     * is unpredictable and should be ignored.
524*593dc095SDavid du Colombier     */
525*593dc095SDavid du Colombier    gx_color_enc_sep_lin_t separable_and_linear;
526*593dc095SDavid du Colombier    byte                   comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
527*593dc095SDavid du Colombier    byte                   comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
528*593dc095SDavid du Colombier    gx_color_index         comp_mask[GX_DEVICE_COLOR_MAX_COMPONENTS];
529*593dc095SDavid du Colombier    /*
530*593dc095SDavid du Colombier     * Pointer to name for the process color model.
531*593dc095SDavid du Colombier     */
532*593dc095SDavid du Colombier    const char * cm_name;
533*593dc095SDavid du Colombier
534*593dc095SDavid du Colombier} gx_device_color_info;
535*593dc095SDavid du Colombier</pre>
5367dd7cddfSDavid du Colombier</blockquote>
5377dd7cddfSDavid du Colombier
5387dd7cddfSDavid du Colombier<p>
539*593dc095SDavid du ColombierNote: See <a href="#Changing_color_info_data">Changing color_info data</a> before changing
540*593dc095SDavid du Colombierany information in the <b><tt>color_info structure</tt></b> for a device.
541*593dc095SDavid du Colombier
542*593dc095SDavid du Colombier<p>
543*593dc095SDavid du ColombierIt is recommended that the values for this structure be defined using one
544*593dc095SDavid du Colombierof the standard macros provided for this purpose. This allows for future
545*593dc095SDavid du Colombierchanges to be made to the structure without changes being required in the
546*593dc095SDavid du Colombieractual device code.
547*593dc095SDavid du Colombier
548*593dc095SDavid du Colombier<p>
549*593dc095SDavid du ColombierThe following macros (in <a href="../src/gxdevcli.h">gxdevcli.h</a>) provide
5503ff48bf5SDavid du Colombierconvenient shorthands for initializing this structure for ordinary
5513ff48bf5SDavid du Colombierblack-and-white or color devices:
5527dd7cddfSDavid du Colombier
5537dd7cddfSDavid du Colombier<blockquote>
5547dd7cddfSDavid du Colombier<b><tt>#define dci_black_and_white</tt></b> ...<br>
5557dd7cddfSDavid du Colombier<b><tt>#define dci_color(depth,maxv,dither)</tt></b> ...
5567dd7cddfSDavid du Colombier</blockquote>
5577dd7cddfSDavid du Colombier
5587dd7cddfSDavid du Colombier<p>
559*593dc095SDavid du ColombierThe <b><tt>#define dci_black_and_white</tt></b> macro defines a
560*593dc095SDavid du Colombiersingle bit monochrome device (For example: a typical monochrome printer device.)
561*593dc095SDavid du Colombier
562*593dc095SDavid du Colombier<p>
563*593dc095SDavid du ColombierThe <b><tt>#define dci_color(depth,maxv,dither)</tt></b> macro can be used
564*593dc095SDavid du Colombierto define a 24 bit RGB device or a 4 or 32 bit CMYK device.
565*593dc095SDavid du Colombier
566*593dc095SDavid du Colombier<p>
567*593dc095SDavid du ColombierThe <b><tt>#define dci_extended_alpha_values</tt></b> macro (in
568*593dc095SDavid du Colombier<a href="../src/gxdevcli.h">gxdevcli.h</a>)
569*593dc095SDavid du Colombierspecifies most of the current fields in the structure. However this macro allows
570*593dc095SDavid du Colombieronly the default setting for the comp_shift, comp_bits, and comp_mask fields
571*593dc095SDavid du Colombierto be set. Any device which requires a non-default setting for these fields
572*593dc095SDavid du Colombierhas to correctly these fields during the device open procedure.
573*593dc095SDavid du ColombierSee
574*593dc095SDavid du Colombier<a href="#sep_and_linear_fields">Separable and linear fields></a> and
575*593dc095SDavid du Colombier<a href="#Changing_color_info_data">Changing color_info data</a>.
576*593dc095SDavid du Colombier
577*593dc095SDavid du Colombier<p>
5787dd7cddfSDavid du ColombierThe idea is that a device has a certain number of gray levels
5797dd7cddfSDavid du Colombier(<b><tt>max_gray</tt></b>+1) and a certain number of colors
5807dd7cddfSDavid du Colombier(<b><tt>max_rgb</tt></b>+1) that it can produce directly.  When Ghostscript
581*593dc095SDavid du Colombierwants to render a given color space color value as a device color, it first tests
582*593dc095SDavid du Colombierwhether the color is a gray level and if so:
5837dd7cddfSDavid du Colombier
5847dd7cddfSDavid du Colombier<blockquote>
5857dd7cddfSDavid du ColombierIf <b><tt>max_gray</tt></b> is large (&gt;= 31), Ghostscript asks the
5867dd7cddfSDavid du Colombierdevice to approximate the gray level directly.  If the device returns a
5877dd7cddfSDavid du Colombiervalid <b><tt>gx_color_index</tt></b>, Ghostscript uses it.  Otherwise,
5887dd7cddfSDavid du ColombierGhostscript assumes that the device can represent
5897dd7cddfSDavid du Colombier<b><tt>dither_gray</tt></b> distinct gray levels, equally spaced along the
5907dd7cddfSDavid du Colombierdiagonal of the color cube, and uses the two nearest ones to the desired
5917dd7cddfSDavid du Colombiercolor for halftoning.
5927dd7cddfSDavid du Colombier</blockquote>
5937dd7cddfSDavid du Colombier
5947dd7cddfSDavid du Colombier<p>
5957dd7cddfSDavid du ColombierIf the color is not a gray level:
5967dd7cddfSDavid du Colombier
5977dd7cddfSDavid du Colombier<blockquote>
5987dd7cddfSDavid du ColombierIf <b><tt>max_rgb</tt></b> is large (&gt;= 31), Ghostscript asks the device
5997dd7cddfSDavid du Colombierto approximate the color directly.  If the device returns a valid
6007dd7cddfSDavid du Colombier<b><tt>gx_color_index</tt></b>, Ghostscript uses it.  Otherwise,
6017dd7cddfSDavid du ColombierGhostscript assumes that the device can represent
6027dd7cddfSDavid du Colombier
6037dd7cddfSDavid du Colombier<blockquote>
6047dd7cddfSDavid du Colombier<b><tt>dither_rgb</tt></b> &times; <b><tt>dither_rgb</tt></b> &times; <b><tt>dither_rgb</tt></b>
6057dd7cddfSDavid du Colombier</blockquote>
6067dd7cddfSDavid du Colombier
6077dd7cddfSDavid du Colombier<p>
6087dd7cddfSDavid du Colombierdistinct colors, equally spaced throughout the color cube, and uses two of
6097dd7cddfSDavid du Colombierthe nearest ones to the desired color for halftoning.
6107dd7cddfSDavid du Colombier</blockquote>
6117dd7cddfSDavid du Colombier
612*593dc095SDavid du Colombier<h4><a name="sep_and_linear_fields"></a>Separable and linear fields</h4>
613*593dc095SDavid du Colombier<p>
614*593dc095SDavid du ColombierThe three fields <b><tt>comp_shift</tt></b>, <b><tt>comp_bits</tt></b>, and
615*593dc095SDavid du Colombier<b><tt>comp_mask</tt></b> are only used if the <b><tt>separable_and_linear</tt></b>
616*593dc095SDavid du Colombierfield is set to <b><tt>GX_CINFO_SEP_LIN</tt></b>. In this situation a <b><tt>gx_color_index</tt></b>
617*593dc095SDavid du Colombiervalue must represent a combination created by or'ing bits for each of the devices's
618*593dc095SDavid du Colombieroutput colorants. The <b><tt>comp_shift</tt></b> array defines the location
619*593dc095SDavid du Colombier(shift count) of each colorants bits in the output gx_color_index value. The
620*593dc095SDavid du Colombier<b><tt>comp_bits</tt></b> array defines the number of bits for each colorant.
621*593dc095SDavid du ColombierThe <b><tt>comp_mask</tt></b> array contains a mask which can be used to isolate
622*593dc095SDavid du Colombierthe bits for each colorant. These fields must be set if the device supports
623*593dc095SDavid du Colombiermore than four colorants.
624*593dc095SDavid du Colombier
625*593dc095SDavid du Colombier<h4><a name="Changing_color_info_data"></a>Changing color_info data</h4>
626*593dc095SDavid du Colombier
627*593dc095SDavid du Colombier<p> For most devices, the information in the device's <tt><b>color_info</b></tt>
628*593dc095SDavid du Colombierstructure is defined by the various device definition macros and the data remains
629*593dc095SDavid du Colombierconstant during the entire existence of the device. In general the Ghostscript
630*593dc095SDavid du Colombiergraphics assumes that the information is constant. However some devices want
631*593dc095SDavid du Colombierto modify the data in this structure.
632*593dc095SDavid du Colombier
633*593dc095SDavid du Colombier<p>
634*593dc095SDavid du ColombierThe device's <b><tt>put_params</tt></b> procedure may change
635*593dc095SDavid du Colombier<b><tt>color_info</tt></b> field values.
636*593dc095SDavid du ColombierAfter the data has been modified then the
637*593dc095SDavid du Colombierdevice should be closed (via a call to <tt><b>gs_closedevice</b></tt>). Closing
638*593dc095SDavid du Colombierthe device will erase the current page so these changes should only be made
639*593dc095SDavid du Colombierbefore anything has been drawn on a page.
640*593dc095SDavid du Colombier
641*593dc095SDavid du Colombier<p> The device's <tt><b>open_device</b></tt> procedure may change
642*593dc095SDavid du Colombier<b><tt>color_info</tt></b> field values. These changes should be done before
643*593dc095SDavid du Colombiercalling any other procedures are called.
644*593dc095SDavid du Colombier
645*593dc095SDavid du Colombier<p>
646*593dc095SDavid du ColombierThe Ghostscript graphics library
647*593dc095SDavid du Colombieruses some of the data in <b><tt>color_info</tt></b> to set the default
648*593dc095SDavid du Colombierprocedures for the
649*593dc095SDavid du Colombier<b><tt>get_color_mapping_procs</tt></b>,
650*593dc095SDavid du Colombier<b><tt>get_color_comp_index</tt></b>,
651*593dc095SDavid du Colombier<b><tt>encode_color</tt></b>, and
652*593dc095SDavid du Colombier<b><tt>decode_color</tt></b> procedures.
653*593dc095SDavid du ColombierThese default procedures are set when the
654*593dc095SDavid du Colombierdevice is originally created. If any changes are made to the
655*593dc095SDavid du Colombier<b><tt>color_info</tt></b> fields then the device's <b><tt>open_device</tt></b>
656*593dc095SDavid du Colombierprocedure
657*593dc095SDavid du Colombierhas responsibility for insuring that the correct procedures are contained
658*593dc095SDavid du Colombierin the device structure. (For an example, see the display device open procedure
659*593dc095SDavid du Colombier<b><tt>display_open</tt></b> and its subroutine <b><tt>display_set_color_format
660*593dc095SDavid du Colombier</tt></b> (in <a href="../src/gdevdisp.c">gdevdisp</a>).
661*593dc095SDavid du Colombier
662*593dc095SDavid du Colombier
6633ff48bf5SDavid du Colombier<h3><a name="Types"></a>Types</h3>
6647dd7cddfSDavid du Colombier
6657dd7cddfSDavid du Colombier<p>
6667dd7cddfSDavid du ColombierHere is a brief explanation of the various types that appear as parameters
6677dd7cddfSDavid du Colombieror results of the drivers.
6687dd7cddfSDavid du Colombier
6697dd7cddfSDavid du Colombier<dl>
670*593dc095SDavid du Colombier<dt><b><tt>frac</tt></b> (defined in <a href="../src/gxfrac.h">gxfrac.h</a>)
671*593dc095SDavid du Colombier<dd>This is the type used to represent color values for the input to the
672*593dc095SDavid du Colombiercolor model mapping procedures. It is currently defined as a short.  It has a
673*593dc095SDavid du Colombierrange of <b><tt>frac_0</tt></b> to <b><tt>frac_1</tt></b>.
674*593dc095SDavid du Colombier</dl>
675*593dc095SDavid du Colombier
676*593dc095SDavid du Colombier<dl>
677*593dc095SDavid du Colombier<dt><b><tt>gx_color_value</tt></b> (defined in
678*593dc095SDavid du Colombier<a href="../src/gxdevice.h">gxdevice.h</a>)
6797dd7cddfSDavid du Colombier<dd>This is the type used to represent RGB or CMYK color values.  It is
6807dd7cddfSDavid du Colombiercurrently equivalent to unsigned short.  However, Ghostscript may use less
6817dd7cddfSDavid du Colombierthan the full range of the type to represent color values:
6827dd7cddfSDavid du Colombier<b><tt>gx_color_value_bits</tt></b> is the number of bits actually used,
6837dd7cddfSDavid du Colombierand <b><tt>gx_max_color_value</tt></b> is the maximum value, equal to
6847dd7cddfSDavid du Colombier(2^<small><sup><b><tt>gx_max_color_value_bits</tt></b></sup></small>)-1.
6857dd7cddfSDavid du Colombier</dl>
6867dd7cddfSDavid du Colombier
6877dd7cddfSDavid du Colombier<dl>
688*593dc095SDavid du Colombier<dt><b><tt>gx_device</tt></b> (defined in
689*593dc095SDavid du Colombier<a href="../src/gxdevice.h">gxdevice.h</a>)
6907dd7cddfSDavid du Colombier<dd>This is the device structure, as explained above.
6917dd7cddfSDavid du Colombier</dl>
6927dd7cddfSDavid du Colombier
6937dd7cddfSDavid du Colombier<dl>
694*593dc095SDavid du Colombier<dt><b><tt>gs_matrix</tt></b> (defined in
695*593dc095SDavid du Colombier<a href="../src/gsmatrix.h">gsmatrix.h</a>)
6967dd7cddfSDavid du Colombier<dd>This is a 2-D homogeneous coordinate transformation matrix, used by
6977dd7cddfSDavid du Colombiermany Ghostscript operators.
6987dd7cddfSDavid du Colombier</dl>
6997dd7cddfSDavid du Colombier
7007dd7cddfSDavid du Colombier<dl>
701*593dc095SDavid du Colombier<dt><b><tt>gx_color_index</tt></b> (defined in
702*593dc095SDavid du Colombier<a href="../src/gxcindex.h">gxcindex.h</a>)
7037dd7cddfSDavid du Colombier<dd>This is meant to be whatever the driver uses to represent a device
7047dd7cddfSDavid du Colombiercolor.  For example, it might be an index in a color map, or it might be R,
705*593dc095SDavid du ColombierG, and B values packed into a single integer.  The Ghostscript graphics library
706*593dc095SDavid du Colombiergets <b><tt>gx_color_index</tt></b> values from the device's
707*593dc095SDavid du Colombier<b><tt>encode_color</tt></b> and hands them back as arguments to several other
708*593dc095SDavid du Colombierprocedures. If the <b><tt>separable_and_linear</tt></b> field in the device's
709*593dc095SDavid du Colombier<b><tt>color_info</tt></b> structure is not set to
710*593dc095SDavid du Colombier<b><tt>GX_CINFO_SEP_LIN</tt></b> then Ghostscript does not do
711*593dc095SDavid du Colombierany computations with <b><tt>gx_color_index</tt></b> values.
712*593dc095SDavid du Colombier
713*593dc095SDavid du Colombier<p>
714*593dc095SDavid du ColombierThe special
7157dd7cddfSDavid du Colombiervalue <b><tt>gx_no_color_index</tt></b> (defined as
716*593dc095SDavid du Colombier<b><tt>(~(gx_color_index)(0))</tt></b>&nbsp;) means "transparent" for some of
717*593dc095SDavid du Colombierthe procedures.
718*593dc095SDavid du Colombier
719*593dc095SDavid du Colombier<p>
720*593dc095SDavid du ColombierThe size of <b><tt>gx_color_index</tt></b> can be either 32 or 64 bits. The
721*593dc095SDavid du Colombierchoice depends upon the architecture of the CPU and the compiler. The default
722*593dc095SDavid du Colombiertype definition is simply:
7237dd7cddfSDavid du Colombier
7247dd7cddfSDavid du Colombier<blockquote><b><tt>
7257dd7cddfSDavid du Colombiertypedef unsigned long gx_color_index;
7267dd7cddfSDavid du Colombier</tt></b></blockquote>
727*593dc095SDavid du Colombier
728*593dc095SDavid du ColombierHowever if <b><tt>GX_COLOR_INDEX_TYPE</tt></b> is defined, then it is used
729*593dc095SDavid du Colombieras the type for <b><tt>gx_color_index</tt></b>.
730*593dc095SDavid du Colombier
731*593dc095SDavid du Colombier<blockquote><b><tt>
732*593dc095SDavid du Colombiertypedef GX_COLOR_INDEX_TYPE gx_color_index;
733*593dc095SDavid du Colombier</tt></b></blockquote>
734*593dc095SDavid du Colombier
735*593dc095SDavid du ColombierThe smaller size (32 bits) may produce more efficient or faster executing
736*593dc095SDavid du Colombiercode. The larger size (64 bits) is needed for representing either more
737*593dc095SDavid du Colombierbits per component or more components. An example of the later case is
738*593dc095SDavid du Colombiera device that supports 8 bit contone colorants using a DeviceCMYK process
739*593dc095SDavid du Colombiercolor model with its four colorants and also supports additional spot
740*593dc095SDavid du Colombiercolorants.
741*593dc095SDavid du Colombier
742*593dc095SDavid du Colombier<p>
743*593dc095SDavid du ColombierCurrently autoconf attempts to find a 64 bit type definition for the
744*593dc095SDavid du Colombiercompiler being used, and if a 64 bit type is found then
745*593dc095SDavid du Colombier<b><tt>GX_COLOR_INDEX_TYPE</tt></b> is set to the type.
746*593dc095SDavid du Colombier
747*593dc095SDavid du Colombier<p>
748*593dc095SDavid du ColombierFor Microsoft and the MSVC compiler, <b><tt>GX_COLOR_INDEX_TYPE</tt></b> will
749*593dc095SDavid du Colombierbe set to <b><tt>unsigned _int64</tt></b> if <b><tt>USE_LARGE_COLOR_INDEX</tt></b>
750*593dc095SDavid du Colombieris set to 1 either on the make command line or by editing the definition
751*593dc095SDavid du Colombier in <a href="../src/msvc32.mak">msvc32.mak</a>
7527dd7cddfSDavid du Colombier</dl>
7537dd7cddfSDavid du Colombier
7547dd7cddfSDavid du Colombier<dl>
7553ff48bf5SDavid du Colombier<dt><b><tt>gs_param_list</tt></b> (defined in <a
7563ff48bf5SDavid du Colombierhref="../src/gsparam.h">gsparam.h</a>)
7577dd7cddfSDavid du Colombier  <dd>This is a parameter list, which is used to read and set attributes in a
7583ff48bf5SDavid du Colombierdevice.  See the comments in <a href="../src/gsparam.h">gsparam.h</a>, and
7593ff48bf5SDavid du Colombierthe <a href="#Parameters">description of the <b><tt>get_params</tt></b> and
7607dd7cddfSDavid du Colombier<b><tt>put_params</tt></b> procedures</a> below, for more detail.
7617dd7cddfSDavid du Colombier</dl>
7627dd7cddfSDavid du Colombier
7637dd7cddfSDavid du Colombier<dl>
7643ff48bf5SDavid du Colombier<dt><b><tt>gx_tile_bitmap</tt></b> (defined in
7653ff48bf5SDavid du Colombier<a href="../src/gxbitmap.h">gxbitmap.h</a>)
7663ff48bf5SDavid du Colombier<br><b><tt>gx_strip_bitmap</tt></b> (defined in
7673ff48bf5SDavid du Colombier<a href="../src/gxbitmap.h">gxbitmap.h</a>)
7687dd7cddfSDavid du Colombier<dd>These structure types represent bitmaps to be used as a tile for
7697dd7cddfSDavid du Colombierfilling a region (rectangle).  <b><tt>gx_tile_bitmap</tt></b> is an older
7707dd7cddfSDavid du Colombiertype lacking <b><tt>shift</tt></b> and <b><tt>rep_shift</tt></b>;
7717dd7cddfSDavid du Colombier<b><tt>gx_strip_bitmap</tt></b> has superseded it, and it should not be
7727dd7cddfSDavid du Colombierused in new code.  Here is a copy of the relevant part of the file:
7737dd7cddfSDavid du Colombier
7747dd7cddfSDavid du Colombier<blockquote>
775*593dc095SDavid du Colombier<pre>
776*593dc095SDavid du Colombier/*
7777dd7cddfSDavid du Colombier * Structure for describing stored bitmaps.
7787dd7cddfSDavid du Colombier * Bitmaps are stored bit-big-endian (i.e., the 2^7 bit of the first
7797dd7cddfSDavid du Colombier * byte corresponds to x=0), as a sequence of bytes (i.e., you can't
7807dd7cddfSDavid du Colombier * do word-oriented operations on them if you're on a little-endian
7817dd7cddfSDavid du Colombier * platform like the Intel 80x86 or VAX).  Each scan line must start on
7827dd7cddfSDavid du Colombier * a (32-bit) word boundary, and hence is padded to a word boundary,
7837dd7cddfSDavid du Colombier * although this should rarely be of concern, since the raster and width
7847dd7cddfSDavid du Colombier * are specified individually.  The first scan line corresponds to y=0
7857dd7cddfSDavid du Colombier * in whatever coordinate system is relevant.
7867dd7cddfSDavid du Colombier *
7877dd7cddfSDavid du Colombier * For bitmaps used as halftone tiles, we may replicate the tile in
7887dd7cddfSDavid du Colombier * X and/or Y, but it is still valuable to know the true tile dimensions
7897dd7cddfSDavid du Colombier * (i.e., the dimensions prior to replication).  Requirements:
7907dd7cddfSDavid du Colombier *      width % rep_width = 0
7917dd7cddfSDavid du Colombier *      height % rep_height = 0
7927dd7cddfSDavid du Colombier *
7937dd7cddfSDavid du Colombier * For halftones at arbitrary angles, we provide for storing the halftone
7947dd7cddfSDavid du Colombier * data as a strip that must be shifted in X for different values of Y.
7957dd7cddfSDavid du Colombier * For an ordinary (non-shifted) halftone that has a repetition width of
7967dd7cddfSDavid du Colombier * W and a repetition height of H, the pixel at coordinate (X,Y)
7977dd7cddfSDavid du Colombier * corresponds to halftone pixel (X mod W, Y mod H), ignoring phase;
7987dd7cddfSDavid du Colombier * for a shifted halftone with shift S, the pixel at (X,Y) corresponds
7997dd7cddfSDavid du Colombier * to halftone pixel ((X + S * floor(Y/H)) mod W, Y mod H).  Requirements:
8007dd7cddfSDavid du Colombier *      strip_shift &lt; rep_width
8017dd7cddfSDavid du Colombier *      strip_height % rep_height = 0
8027dd7cddfSDavid du Colombier *      shift = (strip_shift * (size.y / strip_height)) % rep_width
8037dd7cddfSDavid du Colombier */
8047dd7cddfSDavid du Colombiertypedef struct gx_strip_bitmap_s {
8057dd7cddfSDavid du Colombier        byte *data;
8067dd7cddfSDavid du Colombier        int raster;                     /* bytes per scan line */
8077dd7cddfSDavid du Colombier        gs_int_point size;              /* width, height */
8087dd7cddfSDavid du Colombier        gx_bitmap_id id;
8097dd7cddfSDavid du Colombier        ushort rep_width, rep_height;   /* true size of tile */
8107dd7cddfSDavid du Colombier        ushort strip_height;
8117dd7cddfSDavid du Colombier        ushort strip_shift;
8127dd7cddfSDavid du Colombier        ushort shift;
8137dd7cddfSDavid du Colombier} gx_strip_bitmap;</pre>
8147dd7cddfSDavid du Colombier</blockquote>
8157dd7cddfSDavid du Colombier</dl>
8167dd7cddfSDavid du Colombier
8177dd7cddfSDavid du Colombier<hr>
8187dd7cddfSDavid du Colombier
8193ff48bf5SDavid du Colombier<h2><a name="Coding_conventions"></a>Coding conventions</h2>
8207dd7cddfSDavid du Colombier
8217dd7cddfSDavid du Colombier<p>
8227dd7cddfSDavid du ColombierAll the driver procedures defined below that return <b><tt>int</tt></b>
8237dd7cddfSDavid du Colombierresults return 0 on success, or an appropriate negative error code in the
8243ff48bf5SDavid du Colombiercase of error conditions.  The error codes are defined in <a
8253ff48bf5SDavid du Colombierhref="../src/gserrors.h">gserrors.h</a>; they correspond directly to the
8263ff48bf5SDavid du Colombiererrors defined in the PostScript language reference manuals.  The most
8273ff48bf5SDavid du Colombiercommon ones for drivers are:
8287dd7cddfSDavid du Colombier
8297dd7cddfSDavid du Colombier<blockquote><dl>
8307dd7cddfSDavid du Colombier<dt><b><tt>gs_error_invalidfileaccess</tt></b>
8317dd7cddfSDavid du Colombier<dd>An attempt to open a file failed.
8327dd7cddfSDavid du Colombier
8337dd7cddfSDavid du Colombier<dt><b><tt>gs_error_ioerror</tt></b>
8347dd7cddfSDavid du Colombier<dd>An error occurred in reading or writing a file.
8357dd7cddfSDavid du Colombier
8367dd7cddfSDavid du Colombier<dt><b><tt>gs_error_limitcheck</tt></b>
8377dd7cddfSDavid du Colombier <dd>An otherwise valid parameter value was too large for the
8387dd7cddfSDavid du Colombierimplementation.
8397dd7cddfSDavid du Colombier
8407dd7cddfSDavid du Colombier<dt><b><tt>gs_error_rangecheck</tt></b>
8417dd7cddfSDavid du Colombier<dd>A parameter was outside the valid range.
8427dd7cddfSDavid du Colombier
8437dd7cddfSDavid du Colombier<dt><b><tt>gs_error_VMerror</tt></b>
8447dd7cddfSDavid du Colombier<dd>An attempt to allocate memory failed.  (If this happens, the procedure
8457dd7cddfSDavid du Colombiershould release all memory it allocated before it returns.)
8467dd7cddfSDavid du Colombier</dl></blockquote>
8477dd7cddfSDavid du Colombier
8487dd7cddfSDavid du Colombier<p>
8497dd7cddfSDavid du ColombierIf a driver does return an error, rather than a simple return statement it
8503ff48bf5SDavid du Colombiershould use the <b><tt>return_error</tt></b> macro defined in <a
8513ff48bf5SDavid du Colombierhref="../src/gx.h">gx.h</a>, which is automatically included by <a
8523ff48bf5SDavid du Colombierhref="../src/gdevprn.h">gdevprn.h</a> but not by <a
8533ff48bf5SDavid du Colombierhref="../src/gserrors.h">gserrors.h</a>.  For example
8547dd7cddfSDavid du Colombier
855*593dc095SDavid du Colombier<blockquote>
856*593dc095SDavid du Colombier<b><tt> return_error(gs_error_VMerror);
8577dd7cddfSDavid du Colombier</tt></b></blockquote>
8587dd7cddfSDavid du Colombier
8593ff48bf5SDavid du Colombier<h3><a name="Allocating_storage"></a>Allocating storage</h3>
8607dd7cddfSDavid du Colombier
8617dd7cddfSDavid du Colombier<p>
8627dd7cddfSDavid du ColombierWhile most drivers (especially printer drivers) follow a very similar
8637dd7cddfSDavid du Colombiertemplate, there is one important coding convention that is not obvious from
8647dd7cddfSDavid du Colombierreading the code for existing drivers: driver procedures must not use
8657dd7cddfSDavid du Colombier<b><tt>malloc</tt></b> to allocate any storage that stays around after the
8667dd7cddfSDavid du Colombierprocedure returns. Instead, they must use <b><tt>gs_malloc</tt></b> and
8677dd7cddfSDavid du Colombier<b><tt>gs_free</tt></b>, which have slightly different calling conventions.
8683ff48bf5SDavid du Colombier(The prototypes for these are in <a href="../src/gsmemory.h">gsmemory.h</a>,
8693ff48bf5SDavid du Colombierwhich is included in <a href="../src/gx.h">gx.h</a>, which is included in <a
8703ff48bf5SDavid du Colombierhref="../src/gdevprn.h">gdevprn.h</a>.) This is necessary so that
8713ff48bf5SDavid du ColombierGhostscript can clean up all allocated memory before exiting, which is
8723ff48bf5SDavid du Colombieressential in environments that provide only single-address-space
8733ff48bf5SDavid du Colombiermulti-tasking (some versions of Microsoft Windows).
8747dd7cddfSDavid du Colombier
8757dd7cddfSDavid du Colombier<blockquote>
8767dd7cddfSDavid du Colombier<pre>char *gs_malloc(uint num_elements, uint element_size,
8777dd7cddfSDavid du Colombier  const char *client_name);</pre>
8787dd7cddfSDavid du Colombier</blockquote>
8797dd7cddfSDavid du Colombier
8807dd7cddfSDavid du Colombier<p>
8817dd7cddfSDavid du ColombierLike <b><tt>calloc</tt></b>, but unlike <b><tt>malloc</tt></b>,
8827dd7cddfSDavid du Colombier<b><tt>gs_malloc</tt></b> takes an element count and an element size. For
883*593dc095SDavid du Colombierstructures, <b><tt>num_elements</tt></b> is 1 andi
8847dd7cddfSDavid du Colombier<b><tt>element_size</tt></b> is <b><tt>sizeof</tt></b> the structure; for
8857dd7cddfSDavid du Colombierbyte arrays, <b><tt>num_elements</tt></b> is the number of bytes and
8867dd7cddfSDavid du Colombier<b><tt>element_size</tt></b> is 1. Unlike <b><tt>calloc</tt></b>,
8877dd7cddfSDavid du Colombier<b><tt>gs_malloc</tt></b> does <b>not</b> clear the block of storage.
8887dd7cddfSDavid du Colombier
8897dd7cddfSDavid du Colombier<p>
8907dd7cddfSDavid du ColombierThe <b><tt>client_name</tt></b> is used for tracing and debugging.  It must
8917dd7cddfSDavid du Colombierbe a real string, not <b><tt>NULL</tt></b>.  Normally it is the name of the
8927dd7cddfSDavid du Colombierprocedure in which the call occurs.
8937dd7cddfSDavid du Colombier
8947dd7cddfSDavid du Colombier<blockquote>
8957dd7cddfSDavid du Colombier<pre>void gs_free(char *data, uint num_elements, uint element_size,
8967dd7cddfSDavid du Colombier  const char *client_name);</pre>
8977dd7cddfSDavid du Colombier</blockquote>
8987dd7cddfSDavid du Colombier
8997dd7cddfSDavid du Colombier<p>
9007dd7cddfSDavid du ColombierUnlike <b><tt>free</tt></b>, <b><tt>gs_free</tt></b> demands that
9017dd7cddfSDavid du Colombier<b><tt>num_elements</tt></b> and element_size be supplied. It also
9027dd7cddfSDavid du Colombierrequires a client name, like <b><tt>gs_malloc</tt></b>.
9037dd7cddfSDavid du Colombier
9043ff48bf5SDavid du Colombier<h3><a name="Driver_instance_allocation"></a>Driver instance allocation</h3>
9057dd7cddfSDavid du Colombier
906*593dc095SDavid du Colombier<p>i
9077dd7cddfSDavid du ColombierAll driver instances allocated by Ghostscript's standard allocator must
9087dd7cddfSDavid du Colombierpoint to a "structure descriptor" that tells the garbage collector how to
9097dd7cddfSDavid du Colombiertrace pointers in the structure. For drivers registered in the normal way
9107dd7cddfSDavid du Colombier(using the makefile approach described above), no special care is needed as
9117dd7cddfSDavid du Colombierlong as instances are created only by calling the
9123ff48bf5SDavid du Colombier<b><tt>gs_copydevice</tt></b> procedure defined in <a
9133ff48bf5SDavid du Colombierhref="../src/gsdevice.h">gsdevice.h</a>. If you have a need to define
9143ff48bf5SDavid du Colombierdevices that are not registered in this way, you must fill in the stype
9153ff48bf5SDavid du Colombiermember in any dynamically allocated instances with a pointer to the same
9163ff48bf5SDavid du Colombierstructure descriptor used to allocate the instance. For more information
9173ff48bf5SDavid du Colombierabout structure descriptors, see <a href="../src/gsmemory.h">gsmemory.h</a>
9183ff48bf5SDavid du Colombierand <a href="../src/gsstruct.h">gsstruct.h</a>.
9197dd7cddfSDavid du Colombier
9207dd7cddfSDavid du Colombier<hr>
9217dd7cddfSDavid du Colombier
9223ff48bf5SDavid du Colombier<h2><a name="Printer_drivers"></a>Printer drivers</h2>
9237dd7cddfSDavid du Colombier
9247dd7cddfSDavid du Colombier<p>
9257dd7cddfSDavid du ColombierPrinter drivers (which include drivers that write some kind of raster file)
926*593dc095SDavid du Colombierare especially simple to implement.
927*593dc095SDavid du ColombierThe printer driver must implement a <b><tt>print_page</tt></b> or
9283ff48bf5SDavid du Colombier<b><tt>print_page_copies</tt></b> procedure.  There are macros in <a
9293ff48bf5SDavid du Colombierhref="../src/gdevprn.h">gdevprn.h</a> that generate the device structure for
9303ff48bf5SDavid du Colombiersuch devices, of which the simplest is <b><tt>prn_device</tt></b>; for an
9313ff48bf5SDavid du Colombierexample, see <a href="../src/gdevbj10.c">gdevbj10.c</a>.  If you are writing
9323ff48bf5SDavid du Colombiera printer driver, we suggest you start by reading <a
9333ff48bf5SDavid du Colombierhref="../src/gdevprn.h">gdevprn.h</a> and the <a
9343ff48bf5SDavid du Colombierhref="#Color_mapping">subsection on "Color mapping"</a> below; you may be
9353ff48bf5SDavid du Colombierable to ignore all the rest of the driver procedures.
9367dd7cddfSDavid du Colombier
9377dd7cddfSDavid du Colombier<p>
9387dd7cddfSDavid du ColombierThe <b><tt>print_page</tt></b> procedures are defined as follows:
9397dd7cddfSDavid du Colombier
9407dd7cddfSDavid du Colombier<blockquote>
941*593dc095SDavid du Colombier<pre>int (*print_page)(gx_device_printer *, FILE *)
942*593dc095SDavid du Colombierint (*print_page_copies)(gx_device_printer *, FILE *, int)</pre>
9437dd7cddfSDavid du Colombier</blockquote>
9447dd7cddfSDavid du Colombier
9457dd7cddfSDavid du Colombier<p>
9467dd7cddfSDavid du ColombierThis procedure must read out the rendered image from the device and write
9477dd7cddfSDavid du Colombierwhatever is appropriate to the file.  To read back one or more scan lines
9487dd7cddfSDavid du Colombierof the image, the <b><tt>print_page</tt></b> procedure must call one of the
9497dd7cddfSDavid du Colombierfollowing procedures:
9507dd7cddfSDavid du Colombier
9517dd7cddfSDavid du Colombier<blockquote>
952*593dc095SDavid du Colombier<pre>int gdev_prn_copy_scan_lines(gx_device_printer *pdev, int y, byte *str,
9537dd7cddfSDavid du Colombier    uint size)</pre>
9547dd7cddfSDavid du Colombier</blockquote>
9557dd7cddfSDavid du Colombier
9567dd7cddfSDavid du Colombier<p>
9577dd7cddfSDavid du ColombierFor this procedure, <b><tt>str</tt></b> is where the data should be copied to, and <b><tt>size</tt></b> is
9587dd7cddfSDavid du Colombierthe size of the buffer starting at <b><tt>str</tt></b>.  This procedure returns the number
9597dd7cddfSDavid du Colombierof scan lines copied, or &lt;0 for an error.  <b><tt>str</tt></b> need not be aligned.
9607dd7cddfSDavid du Colombier
9617dd7cddfSDavid du Colombier<blockquote>
9627dd7cddfSDavid du Colombier<pre>int gdev_prn_get_bits(gx_device_printer *pdev, int y, byte *str,
9637dd7cddfSDavid du Colombier  byte **actual_data)</pre>
9647dd7cddfSDavid du Colombier</blockquote>
9657dd7cddfSDavid du Colombier
9667dd7cddfSDavid du Colombier<p>
9677dd7cddfSDavid du ColombierThis procedure reads out exactly one scan line.  If the scan line is
9687dd7cddfSDavid du Colombieravailable in the correct format already, <b><tt>*actual_data</tt></b> is
9697dd7cddfSDavid du Colombierset to point to it; otherwise, the scan line is copied to the buffer
9707dd7cddfSDavid du Colombierstarting at <b><tt>str</tt></b>, and <b><tt>*actual_data</tt></b> is set to
9717dd7cddfSDavid du Colombier<b><tt>str</tt></b>.  This saves a copying step most of the time.
9727dd7cddfSDavid du Colombier<b><tt>str</tt></b> need not be aligned; however, if
9737dd7cddfSDavid du Colombier<b><tt>*actual_data</tt></b> is set to point to an existing scan line, it
9747dd7cddfSDavid du Colombierwill be aligned.  (See the description of the <b><tt>get_bits</tt></b>
9757dd7cddfSDavid du Colombierprocedure below for more details.)
9767dd7cddfSDavid du Colombier
9777dd7cddfSDavid du Colombier<p>
9787dd7cddfSDavid du ColombierIn either case, each row of the image is stored in the form described in
9797dd7cddfSDavid du Colombierthe comment under <b><tt>gx_tile_bitmap</tt></b> above; each pixel takes
9807dd7cddfSDavid du Colombierthe number of bits specified as <b><tt>color_info.depth</tt></b> in the
9817dd7cddfSDavid du Colombierdevice structure, and holds values returned by the device's
982*593dc095SDavid du Colombier<b><tt>encode_color</tt></b> procedure.
9837dd7cddfSDavid du Colombier
9847dd7cddfSDavid du Colombier<p>
9857dd7cddfSDavid du ColombierThe <b><tt>print_page</tt></b> procedure can determine the number of bytes
9867dd7cddfSDavid du Colombierrequired to hold a scan line by calling:
9877dd7cddfSDavid du Colombier
9887dd7cddfSDavid du Colombier<blockquote>
989*593dc095SDavid du Colombier<pre>uint gdev_prn_raster(gx_device_printer *)</pre>
9907dd7cddfSDavid du Colombier</blockquote>
9917dd7cddfSDavid du Colombier
9927dd7cddfSDavid du Colombier<p>
9937dd7cddfSDavid du ColombierFor a very simple concrete example, we suggest reading the code in
9943ff48bf5SDavid du Colombier<b><tt>bit_print_page</tt></b> in <a href="../src/gdevbit.c">gdevbit.c</a>.
9957dd7cddfSDavid du Colombier
9967dd7cddfSDavid du Colombier<p>
9977dd7cddfSDavid du ColombierIf the device provides <b><tt>print_page</tt></b>, Ghostscript will call
9987dd7cddfSDavid du Colombier<b><tt>print_page</tt></b> the requisite number of times to print the
9997dd7cddfSDavid du Colombierdesired number of copies; if the device provides
10007dd7cddfSDavid du Colombier<b><tt>print_page_copies</tt></b>, Ghostscript will call
10017dd7cddfSDavid du Colombier<b><tt>print_page_copies</tt></b> once per page, passing it the desired
10027dd7cddfSDavid du Colombiernumber of copies.
10037dd7cddfSDavid du Colombier
10047dd7cddfSDavid du Colombier<hr>
10057dd7cddfSDavid du Colombier
10063ff48bf5SDavid du Colombier<h2><a name="Driver_procedures"></a>Driver procedures</h2>
10077dd7cddfSDavid du Colombier
10087dd7cddfSDavid du Colombier<p>
10097dd7cddfSDavid du ColombierMost of the procedures that a driver may implement are optional.  If a
10107dd7cddfSDavid du Colombierdevice doesn't supply an optional procedure <b><tt>WXYZ</tt></b>, the entry
10117dd7cddfSDavid du Colombierin the procedure structure may be either <b><tt>gx_default_WXYZ</tt></b>,
10127dd7cddfSDavid du Colombierfor instance <b><tt>gx_default_tile_rectangle</tt></b>, or
10137dd7cddfSDavid du Colombier<b><tt>NULL</tt></b> or 0.  (The device procedure must also call the
10147dd7cddfSDavid du Colombier<b><tt>gx_default_</tt></b> procedure if it doesn't implement the function
10157dd7cddfSDavid du Colombierfor particular values of the arguments.)  Since C compilers supply 0 as the
10167dd7cddfSDavid du Colombiervalue for omitted structure elements, this convention means that statically
10177dd7cddfSDavid du Colombierinitialized procedure structures continue to work even if new (optional)
10187dd7cddfSDavid du Colombiermembers are added.
10197dd7cddfSDavid du Colombier
10203ff48bf5SDavid du Colombier<h3><a name="Life_cycle"></a>Life cycle</h3>
10217dd7cddfSDavid du Colombier
10227dd7cddfSDavid du Colombier<p>
10237dd7cddfSDavid du ColombierA device instance begins life in a closed state.  In this state, no output
10247dd7cddfSDavid du Colombieroperations will occur.  Only the following procedures may be called:
10257dd7cddfSDavid du Colombier
10267dd7cddfSDavid du Colombier<blockquote><b><tt>
10277dd7cddfSDavid du Colombieropen_device<br>
10283ff48bf5SDavid du Colombierfinish_copydevice<br>
10297dd7cddfSDavid du Colombierget_initial_matrix<br>
10307dd7cddfSDavid du Colombierget_params<br>
10317dd7cddfSDavid du Colombierput_params<br>
10327dd7cddfSDavid du Colombierget_hardware_params
10337dd7cddfSDavid du Colombier</tt></b></blockquote>
10347dd7cddfSDavid du Colombier
10357dd7cddfSDavid du Colombier<p>
10367dd7cddfSDavid du ColombierWhen <b><tt>setdevice</tt></b> installs a device instance in the graphics
10377dd7cddfSDavid du Colombierstate, it checks whether the instance is closed or open.  If the instance
10387dd7cddfSDavid du Colombieris closed, <b><tt>setdevice</tt></b> calls the open routine, and then sets
1039*593dc095SDavid du Colombierthe state to open.
1040*593dc095SDavid du Colombier
1041*593dc095SDavid du Colombier<p>
1042*593dc095SDavid du ColombierThere is no user-accessible operation to close a device instance.  This is
1043*593dc095SDavid du Colombiernot an oversight -- it is required in order to enforce the following
1044*593dc095SDavid du Colombierinvariant:
1045*593dc095SDavid du Colombier
1046*593dc095SDavid du Colombier<blockquote>
1047*593dc095SDavid du ColombierIf a device instance is the current device in <em>any</em> graphics state,
1048*593dc095SDavid du Colombierit must be open (have <b><tt>is_open</tt></b> set to true).
1049*593dc095SDavid du Colombier</blockquote>
1050*593dc095SDavid du Colombier
1051*593dc095SDavid du Colombier<p>
1052*593dc095SDavid du ColombierDevice instances are only closed when they are about to
1053*593dc095SDavid du Colombierbe freed, which occurs in three situations:
10547dd7cddfSDavid du Colombier
10557dd7cddfSDavid du Colombier<ul>
10563ff48bf5SDavid du Colombier<li>When a <b><tt>restore</tt></b> occurs, if the instance was created since
10573ff48bf5SDavid du Colombierthe corresponding <b><tt>save</tt></b> and is in a VM being restored.  I.e.,
10583ff48bf5SDavid du Colombierif the instance was created in local VM since a <b><tt>save</tt></b>, it
10593ff48bf5SDavid du Colombierwill always be closed and freed by the corresponding
10603ff48bf5SDavid du Colombier<b><tt>restore</tt></b>; if it was created in global VM, it will only be
10613ff48bf5SDavid du Colombierclosed by the outermost <b><tt>restore</tt></b>, regardless of the save
10623ff48bf5SDavid du Colombierlevel at the time the instance was created.
10633ff48bf5SDavid du Colombier
10643ff48bf5SDavid du Colombier<li>By the garbage collector, if the instance is no longer accessible.
10653ff48bf5SDavid du Colombier
10663ff48bf5SDavid du Colombier<li>When Ghostscript exits (terminates).
10677dd7cddfSDavid du Colombier</ul>
10687dd7cddfSDavid du Colombier
10693ff48bf5SDavid du Colombier<h3><a name="Open_close"></a>Open, close, sync, copy</h3>
10707dd7cddfSDavid du Colombier
10717dd7cddfSDavid du Colombier<dl>
1072*593dc095SDavid du Colombier<dt><b><tt>int (*open_device)(gx_device *)</tt></b> <b><em>[OPTIONAL]</em></b>
10737dd7cddfSDavid du Colombier<dd>Open the device: do any initialization associated with making the device
10747dd7cddfSDavid du Colombierinstance valid. This must be done before any output to the device. The
10757dd7cddfSDavid du Colombierdefault implementation does nothing. <b>NOTE</b>: Clients should never call
10767dd7cddfSDavid du Colombiera device's <b><tt>open_device</tt></b> procedure directly: they should
10777dd7cddfSDavid du Colombieralways call <b><tt>gs_opendevice</tt></b> instead.
10783ff48bf5SDavid du Colombier</dl>
10797dd7cddfSDavid du Colombier
10803ff48bf5SDavid du Colombier<dl>
1081*593dc095SDavid du Colombier<dt><b><tt>int (*finish_copydevice)(gx_device *dev, const gx_device
1082*593dc095SDavid du Colombier*from_dev)</tt></b> <b><em>[OPTIONAL]</em></b> <dd>Perform any cleanup
10833ff48bf5SDavid du Colombierrequired after <b><tt>copydevice</tt></b> has created a new device instance
10843ff48bf5SDavid du Colombierby copying <b><tt>from_dev</tt></b>. If the copy operation should not be
10853ff48bf5SDavid du Colombierallowed, this procedure should return an error; the copy will be freed. The
10863ff48bf5SDavid du Colombierdefault implementation allows copying the device prototype, but does not
10873ff48bf5SDavid du Colombierallow copying device instances, because instances may contain internal
10883ff48bf5SDavid du Colombierpointers that should not be shared between copies, and there is no way to
10893ff48bf5SDavid du Colombierdetermine this from outside the device. <b>NOTE</b>: Clients should never
10903ff48bf5SDavid du Colombiercall a device's <b><tt>finish_copydevice</tt></b> procedure: this procedure
10913ff48bf5SDavid du Colombieris only intended for use by <b><tt>gs_copydevice[2]</tt></b>.
10927dd7cddfSDavid du Colombier</dl>
10937dd7cddfSDavid du Colombier
10947dd7cddfSDavid du Colombier<dl>
1095*593dc095SDavid du Colombier<dt><b><tt>void (*get_initial_matrix)(gx_device *, gs_matrix *)</tt></b> <b><em>[OPTIONAL]</em></b>
10967dd7cddfSDavid du Colombier<dd>Construct the initial transformation matrix mapping user coordinates
10977dd7cddfSDavid du Colombier(nominally 1/72 inch per unit) to device coordinates.  The default
10987dd7cddfSDavid du Colombierprocedure computes this from width, height, and
10997dd7cddfSDavid du Colombier[<b><tt>xy</tt></b>]<b><tt>_pixels_per_inch</tt></b> on the assumption that
11007dd7cddfSDavid du Colombierthe origin is in the upper left corner, that is
11017dd7cddfSDavid du Colombier<blockquote>
11027dd7cddfSDavid du Colombier<b><tt>xx</tt></b> = <b><tt>x_pixels_per_inch</tt></b>/72, <b><tt>xy</tt></b> = 0,<br>
11037dd7cddfSDavid du Colombier<b><tt>yx = 0, yy = -y_pixels_per_inch</tt></b>/72,<br>
11047dd7cddfSDavid du Colombier<b><tt>tx = 0, ty = height</tt></b>.
11057dd7cddfSDavid du Colombier</blockquote>
11067dd7cddfSDavid du Colombier</dl>
11077dd7cddfSDavid du Colombier
11087dd7cddfSDavid du Colombier<dl>
1109*593dc095SDavid du Colombier<dt><b><tt>int (*sync_output)(gx_device *)</tt></b> <b><em>[OPTIONAL]</em></b>
11107dd7cddfSDavid du Colombier<dd>Synchronize the device.  If any output to the device has been
11117dd7cddfSDavid du Colombierbuffered, send or write it now.  Note that this may be called several times
11127dd7cddfSDavid du Colombierin the process of constructing a page, so printer drivers should <b>not</b>
11137dd7cddfSDavid du Colombierimplement this by printing the page.  The default implementation does
11147dd7cddfSDavid du Colombiernothing.
11157dd7cddfSDavid du Colombier</dl>
11167dd7cddfSDavid du Colombier
11177dd7cddfSDavid du Colombier<dl>
1118*593dc095SDavid du Colombier<dt><b><tt>int (*output_page)(gx_device *, int num_copies, int flush)</tt></b> <b><em>[OPTIONAL]</em></b>
11197dd7cddfSDavid du Colombier<dd>Output a fully composed page to the device.  The
11207dd7cddfSDavid du Colombier<b><tt>num_copies</tt></b> argument is the number of copies that should be
11217dd7cddfSDavid du Colombierproduced for a hardcopy device.  (This may be ignored if the driver has
11227dd7cddfSDavid du Colombiersome other way to specify the number of copies.)  The <b><tt>flush</tt></b>
11237dd7cddfSDavid du Colombierargument is true for <b><tt>showpage</tt></b>, false for
11247dd7cddfSDavid du Colombier<b><tt>copypage</tt></b>.  The default definition just calls
11257dd7cddfSDavid du Colombier<b><tt>sync_output</tt></b>.  Printer drivers should implement this by
11267dd7cddfSDavid du Colombierprinting and ejecting the page.
11277dd7cddfSDavid du Colombier</dl>
11287dd7cddfSDavid du Colombier
11297dd7cddfSDavid du Colombier<dl>
1130*593dc095SDavid du Colombier<dt><b><tt>int (*close_device)(gx_device *)</tt></b> <b><em>[OPTIONAL]</em></b>
11317dd7cddfSDavid du Colombier<dd>Close the device: release any associated resources. After this, output
11327dd7cddfSDavid du Colombierto the device is no longer allowed. The default implementation does
11337dd7cddfSDavid du Colombiernothing.  <b>NOTE</b>: Clients should never call a device's
11347dd7cddfSDavid du Colombier<b><tt>close_device</tt></b> procedure directly: they should always call
11357dd7cddfSDavid du Colombier<b><tt>gs_closedevice</tt></b> instead.
11367dd7cddfSDavid du Colombier</dl>
11373ff48bf5SDavid du Colombier<h3><a name="Color_mapping"></a>Color and alpha mapping</h3>
11387dd7cddfSDavid du Colombier
11397dd7cddfSDavid du Colombier<p>
11407dd7cddfSDavid du ColombierNote that code in the Ghostscript library may cache the results of calling
11417dd7cddfSDavid du Colombierone or more of the color mapping procedures.  If the result returned by any
11427dd7cddfSDavid du Colombierof these procedures would change (other than as a result of a change made by
11437dd7cddfSDavid du Colombierthe driver's <b><tt>put_params</tt></b> procedure), the driver must call
11447dd7cddfSDavid du Colombier<b><tt>gx_device_decache_colors(dev)</tt></b>.
11457dd7cddfSDavid du Colombier
1146*593dc095SDavid du Colombier<p>
1147*593dc095SDavid du ColombierThe <b><tt>map_rgb_color</tt></b>, <b><tt>map_color_rgb</tt></b>, and
1148*593dc095SDavid du Colombier<b><tt>map_cmyk_color</tt></b> are obsolete. They have been left
1149*593dc095SDavid du Colombierin the device procedure list for backward compatibility. See the
1150*593dc095SDavid du Colombier<b><tt>encode_color</tt></b> and <b><tt>decode_color</tt></b> procedures
1151*593dc095SDavid du Colombierbelow. To insure that older device drivers are changed to use the new
1152*593dc095SDavid du Colombier<b><tt>encode_color</tt></b> and <b><tt>decode_color</tt></b>
1153*593dc095SDavid du Colombierprocedures,
1154*593dc095SDavid du Colombierthe parameters for the older procedures have been changed to
1155*593dc095SDavid du Colombiermatch the new procedures.  To minimize changes in devices that have
1156*593dc095SDavid du Colombieralready been written, the map_rgb_color and map_cmyk_color routines
1157*593dc095SDavid du Colombierare used as the default value for the encode_color routine.  The
1158*593dc095SDavid du Colombiermap_cmyk_color routine is used if the number of components is four.
1159*593dc095SDavid du ColombierThe map_rgb_color routine is used if the number of components is one
1160*593dc095SDavid du Colombieror three. This works okay for RGB and CMYK process color model devices.
1161*593dc095SDavid du ColombierHowever this does not work properly for gray devices. The encode_color
1162*593dc095SDavid du Colombierroutine for a gray device is only passed one component. Thus the
1163*593dc095SDavid du Colombiermap_rgb_color routine must be modified to only use a single input (instead
1164*593dc095SDavid du Colombierof three).  (See the encode_color and decode_color routines below.)
1165*593dc095SDavid du Colombier
11667dd7cddfSDavid du Colombier
11677dd7cddfSDavid du Colombier<p>
1168*593dc095SDavid du ColombierColors can be specified to the Ghostscript graphics library in a variety
1169*593dc095SDavid du Colombierof forms.  For example, there are a wide variety of color spaces that can
1170*593dc095SDavid du Colombierbe used such as Gray, RGB, CMYK, DeviceN, Separation, Indexed, CIEbasedABC,
1171*593dc095SDavid du Colombieretc.  The graphics library converts the various input color space
1172*593dc095SDavid du Colombiervalues into four base color spaces: Gray, RGB, CMYK, and DeviceN. The
1173*593dc095SDavid du ColombierDeviceN color space allows for specifying values for individual device
1174*593dc095SDavid du Colombiercolorants or spot colors.
11757dd7cddfSDavid du Colombier
11767dd7cddfSDavid du Colombier<p>
1177*593dc095SDavid du ColombierColors are converted by the device in a two step process. The first step
1178*593dc095SDavid du Colombieris to convert a color in one of the base color spaces (Gray, RGB, CMYK,
1179*593dc095SDavid du Colombieror DeviceN) into values for each device colorant.  This transformation is
1180*593dc095SDavid du Colombierdone via a set of procedures provided by the device.  These procedures are
1181*593dc095SDavid du Colombierprovided by the <b><tt>get_color_mapping_procs</tt></b> device procedure.
1182*593dc095SDavid du Colombier
1183*593dc095SDavid du Colombier<p>
1184*593dc095SDavid du ColombierBetween the first and second steps, the graphics library applies transfer
1185*593dc095SDavid du Colombierfunctions to the device colorants. Where needed, the output of the results
1186*593dc095SDavid du Colombierafter the transfer functions is used by the graphics library for halftoning.
1187*593dc095SDavid du Colombier
1188*593dc095SDavid du Colombier<p>
1189*593dc095SDavid du ColombierIn the second step, the device procedure <b><tt>encode_color</tt></b> is
1190*593dc095SDavid du Colombierused to convert the transfer function results into a
1191*593dc095SDavid du Colombier<b><tt>gx_color_index</tt></b> value.
1192*593dc095SDavid du ColombierThe <b><tt>gx_color_index</tt></b> values are passed to specify colors
1193*593dc095SDavid du Colombierto various routines.
1194*593dc095SDavid du ColombierThe choice of the encoding for a <b><tt>gx_color_index</tt></b> is
1195*593dc095SDavid du Colombierup to the device. Common choices are indexes into a color palette or
1196*593dc095SDavid du Colombierseveral integers packed together into a single value. The manner of this
1197*593dc095SDavid du Colombierencoding is usually opaque to the graphics library. The only exception to this
1198*593dc095SDavid du Colombierstatement occurs when halftoning 5 or more colorants. In this case the
1199*593dc095SDavid du Colombiergraphics library assumes that if a colorant values is zero then the
1200*593dc095SDavid du Colombierbits associated with the colorant in the <b><tt>gx_color_index</tt></b>
1201*593dc095SDavid du Colombiervalue are zero.
1202*593dc095SDavid du Colombier
1203*593dc095SDavid du Colombier<dl>
1204*593dc095SDavid du Colombier<dt><b><tt>int get_color_comp_index(const gx_device&nbsp;* dev, const char * pname,
1205*593dc095SDavid du Colombierint name_size, int src_index)</tt></b> <b><em>[OPTIONAL]</em></b>
1206*593dc095SDavid du Colombier<dd>This procedure returns the device colorant number of the given name.
1207*593dc095SDavid du ColombierThe possible return values are -1, 0 to
1208*593dc095SDavid du Colombier<b><tt>GX_DEVICE_COLOR_MAX_COMPONENTS - 1</tt></b>, or
1209*593dc095SDavid du Colombier<b><tt>GX_DEVICE_COLOR_MAX_COMPONENTS</tt></b>. A value of -1 indicates that
1210*593dc095SDavid du Colombierthe specified name is not a colorant for the device. A value of 0 to
1211*593dc095SDavid du Colombier<b><tt>GX_DEVICE_COLOR_MAX_COMPONENTS - 1</tt></b> indicates the colorant number
1212*593dc095SDavid du Colombierof the given name. A value of <b><tt>GX_DEVICE_COLOR_MAX_COMPONENTS</tt></b>
1213*593dc095SDavid du Colombierindicates that the given name is a valid colorant name for the device but the
1214*593dc095SDavid du Colombiercolorant is not currently being used. This is used for implementing names
1215*593dc095SDavid du Colombierwhich are in SeparationColorNames but not in SeparationOrder.
1216*593dc095SDavid du Colombier
1217*593dc095SDavid du Colombier<p>
1218*593dc095SDavid du ColombierThe default procedure returns results based upon process color model
1219*593dc095SDavid du Colombierof DeviceGray, DeviceRGB, or DeviceCMYK selected by
1220*593dc095SDavid du Colombier<b><tt>color_info.num_components</tt></b>. This procedure must be
1221*593dc095SDavid du Colombierdefined if another process color model is used by the device or spot colors are
1222*593dc095SDavid du Colombiersupported by the device.
1223*593dc095SDavid du Colombier</dd>
12247dd7cddfSDavid du Colombier</dl>
12257dd7cddfSDavid du Colombier
12267dd7cddfSDavid du Colombier<dl>
1227*593dc095SDavid du Colombier<dt><b><tt>const gx_cm_color_map_procs&nbsp;* get_color_mapping_procs(const
1228*593dc095SDavid du Colombiergx_device&nbsp;* dev)</tt></b> <b><em>[OPTIONAL]</em></b>
1229*593dc095SDavid du Colombier<dd>This procedure returns a list of three procedures. These procedures
1230*593dc095SDavid du Colombierare used to translate values in either Gray, RGB, or CMYK color spaces
1231*593dc095SDavid du Colombierinto device colorant values. A separate procedure is not required for the
1232*593dc095SDavid du ColombierDeviceN and Separation color spaces since these already represent
1233*593dc095SDavid du Colombierdevice colorants.
1234*593dc095SDavid du Colombier
1235*593dc095SDavid du Colombier<p>
1236*593dc095SDavid du ColombierThe default procedure returns a list of procedures based upon
1237*593dc095SDavid du Colombier<b><tt>color_info.num_components</tt></b>.  These procedures are appropriate
1238*593dc095SDavid du Colombierfor DeviceGray, DeviceRGB, or DeviceCMYK process color model devices. A
1239*593dc095SDavid du Colombierprocedure must be defined if another process color model is used by the
1240*593dc095SDavid du Colombierdevice or spot colors are to be supported.
1241*593dc095SDavid du Colombier</dd>
12427dd7cddfSDavid du Colombier</dl>
12437dd7cddfSDavid du Colombier
12447dd7cddfSDavid du Colombier<dl>
1245*593dc095SDavid du Colombier<dt><b><tt>gx_color_index (*encode_color)(gx_device&nbsp;* dev,
1246*593dc095SDavid du Colombiergx_color_value&nbsp;* cv)</tt></b> <b><em>[OPTIONAL]</em></b>
1247*593dc095SDavid du Colombier<dd>Map a set of device color values into a <b><tt>gx_color_index</tt></b>
1248*593dc095SDavid du Colombiervalue. The range of legal values of the
1249*593dc095SDavid du Colombierarguments is 0 to <b><tt>gx_max_color_value</tt></b>.  The default procedure
1250*593dc095SDavid du Colombierpacks bits into a <b><tt>gx_color_index</tt></b> value based upon the
1251*593dc095SDavid du Colombiervalues in <b><tt>color_info.depth</tt></b> and
1252*593dc095SDavid du Colombier<b><tt>color_info.num_components</tt></b>.
1253*593dc095SDavid du Colombier
1254*593dc095SDavid du Colombier<p>
1255*593dc095SDavid du ColombierNote that the <b><tt>encode_color</tt></b> procedure
1256*593dc095SDavid du Colombiermust not return <b><tt>gx_no_color_index</tt></b> (all 1s).
1257*593dc095SDavid du Colombier</dl>
1258*593dc095SDavid du Colombier
1259*593dc095SDavid du Colombier<dl>
1260*593dc095SDavid du Colombier<dt><b><tt>int (*decode_color)(gx_device&nbsp;*, gx_color_index&nbsp;color,
1261*593dc095SDavid du Colombiergx_color_value&nbsp;*&nbsp;CV)</tt></b> <b><em>[OPTIONAL]</em></b>
1262*593dc095SDavid du Colombier<dd>This is the inverse of the <b><tt>encode_color</tt></b> procedure.
1263*593dc095SDavid du ColombierMap a <b><tt>gx_color_index</tt></b> value to color values.  The default
1264*593dc095SDavid du Colombierprocedure unpacks bits from the <b><tt>gx_color_index</tt></b> value based upon
1265*593dc095SDavid du Colombierthe values in <b><tt>color_info.depth</tt></b> and
1266*593dc095SDavid du Colombier<b><tt>color_info.num_components</tt></b>.
1267*593dc095SDavid du Colombier</dl>
1268*593dc095SDavid du Colombier
1269*593dc095SDavid du Colombier<dl>
1270*593dc095SDavid du Colombier<dt><b><tt>gx_color_index (*map_rgb_alpha_color)(gx_device&nbsp;*,
12717dd7cddfSDavid du Colombiergx_color_value&nbsp;red, gx_color_value&nbsp;green,
1272*593dc095SDavid du Colombiergx_color_value&nbsp;blue, gx_color_value&nbsp;alpha)</tt></b> <b><em>[OPTIONAL]</em></b>
12737dd7cddfSDavid du Colombier<dd>Map a RGB color and an opacity value to a device color.  The range of
12747dd7cddfSDavid du Colombierlegal values of the RGB and alpha arguments is 0 to
12757dd7cddfSDavid du Colombier<b><tt>gx_max_color_value</tt></b>; <b><tt>alpha</tt></b> = 0 means
12767dd7cddfSDavid du Colombiertransparent, <b><tt>alpha</tt></b> = <b><tt>gx_max_color_value</tt></b>
12777dd7cddfSDavid du Colombiermeans fully opaque.  The default is to use the
1278*593dc095SDavid du Colombier<b><tt>encode_color</tt></b> procedure and ignore alpha.
12797dd7cddfSDavid du Colombier
12807dd7cddfSDavid du Colombier<p>
12817dd7cddfSDavid du ColombierNote that if a driver implements <b><tt>map_rgb_alpha_color</tt></b>, it
1282*593dc095SDavid du Colombiermust also implement <b><tt>encode_color</tt></b>, and must implement them
12837dd7cddfSDavid du Colombierin such a way that
12847dd7cddfSDavid du Colombier<b><tt>map_rgb_alpha_color(dev,&nbsp;r,&nbsp;g,&nbsp;b,&nbsp;gx_max_color_value)</tt></b>
12857dd7cddfSDavid du Colombierreturns the same value as
1286*593dc095SDavid du Colombier<b><tt>encode_color(dev,&nbsp;CV)</tt></b>.
12877dd7cddfSDavid du Colombier</dl>
12887dd7cddfSDavid du Colombier
12897dd7cddfSDavid du Colombier<dl>
1290*593dc095SDavid du Colombier<dt><b><tt>int (*map_color_rgb_alpha)(gx_device&nbsp;*,
1291*593dc095SDavid du Colombiergx_color_index&nbsp;color, gx_color_value&nbsp;rgba[4])</tt></b>
12927dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
12937dd7cddfSDavid du Colombier<dd>Map a device color code to RGB and alpha values.  The default
12947dd7cddfSDavid du Colombierimplementation calls <b><tt>map_color_rgb</tt></b> and fills in
12957dd7cddfSDavid du Colombier<b><tt>gx_max_color_value</tt></b> for alpha.
12967dd7cddfSDavid du Colombier
12977dd7cddfSDavid du Colombier<p>
12987dd7cddfSDavid du ColombierNote that if a driver implements <b><tt>map_color_rgb_alpha</tt></b>, it
1299*593dc095SDavid du Colombiermust also implement <b><tt>decode_color</tt></b>, and must implement them
13007dd7cddfSDavid du Colombierin such a way that the first 3 values returned by
13017dd7cddfSDavid du Colombier<b><tt>map_color_rgb_alpha</tt></b> are the same as the values returned by
1302*593dc095SDavid du Colombier<b><tt>decode_color</tt></b>.
13037dd7cddfSDavid du Colombier
13047dd7cddfSDavid du Colombier<p>
1305*593dc095SDavid du ColombierNote that only RGB devices currently support variable opacity; alpha is ignored
1306*593dc095SDavid du Colombieron other devices. The PDF 1.4 transparency features are supported on all devices.
13077dd7cddfSDavid du Colombier</dl>
13087dd7cddfSDavid du Colombier
13097dd7cddfSDavid du Colombier<dl>
13107dd7cddfSDavid du Colombier<dt><b><tt>typedef&nbsp;enum&nbsp;{&nbsp;go_text,
13117dd7cddfSDavid du Colombiergo_graphics&nbsp;}&nbsp;graphic_object_type;&nbsp;int
1312*593dc095SDavid du Colombier(*get_alpha_bits)(gx_device&nbsp;*dev,
1313*593dc095SDavid du Colombiergraphic_object_type&nbsp;type)</tt></b> <b><em>[OPTIONAL] [OBSOLETE]</em></b>
13147dd7cddfSDavid du Colombier<dd>This procedure is no longer used: it is replaced by the
13157dd7cddfSDavid du Colombiercolor_info.anti_alias member of the driver structure.  However, it still
13167dd7cddfSDavid du Colombierappears in the driver procedure vector for backward compatibility.  It
13177dd7cddfSDavid du Colombiershould never be called, and drivers should not implement it.
13187dd7cddfSDavid du Colombier</dl>
13197dd7cddfSDavid du Colombier
1320*593dc095SDavid du Colombier<dl>
1321*593dc095SDavid du Colombier<dt><b><tt>void (*update_spot_equivalent_colors)(gx_device&nbsp;*,
1322*593dc095SDavid du Colombierconst gs_state *)</tt></b>
1323*593dc095SDavid du Colombier<b><em>[OPTIONAL]</em></b>
1324*593dc095SDavid du Colombier<dd>This routine provides a method for the device to gather an equivalent
1325*593dc095SDavid du Colombiercolor for spot colorants. This routine is called when a Separation or DeviceN
1326*593dc095SDavid du Colombiercolor space is installed.  See comments at the start of
1327*593dc095SDavid du Colombier<a href="../src/gsequivc.c">gsequivc.c</a>. Note: This procedure is only needed
1328*593dc095SDavid du Colombierfor devices that support spot colorants and also need to have an equivalent
1329*593dc095SDavid du Colombiercolor for simulating the appearance of the spot colorants.
1330*593dc095SDavid du Colombier</dl>
1331*593dc095SDavid du Colombier
13323ff48bf5SDavid du Colombier<h3><a name="Pixel_level_drawing"></a>Pixel-level drawing</h3>
13337dd7cddfSDavid du Colombier
13347dd7cddfSDavid du Colombier<p>
13357dd7cddfSDavid du ColombierThis group of drawing operations specifies data at the pixel level.  All
13367dd7cddfSDavid du Colombierdrawing operations use device coordinates and device color values.
13377dd7cddfSDavid du Colombier
13387dd7cddfSDavid du Colombier<dl>
1339*593dc095SDavid du Colombier<dt><b><tt>int (*fill_rectangle)(gx_device&nbsp;*, int&nbsp;x,
13407dd7cddfSDavid du Colombierint&nbsp;y, int&nbsp;width, int&nbsp;height,
1341*593dc095SDavid du Colombiergx_color_index&nbsp;color)</tt></b>
13427dd7cddfSDavid du Colombier<dd>Fill a rectangle with a color.  The set of pixels filled is {(px,py) |
13437dd7cddfSDavid du Colombierx &lt;= px &lt; x + width and y &lt;= py &lt; y + height}.  In other words,
13447dd7cddfSDavid du Colombierthe point <em>(x,y)</em> is included in the rectangle, as are
13457dd7cddfSDavid du Colombier<em>(x+w-1,y)</em>, <em>(x,y+h-1)</em>, and <em>(x+w-1,y+h-1)</em>, but
13467dd7cddfSDavid du Colombier<b><em>not</em></b> <em>(x+w,y)</em>, <em>(x,y+h)</em>, or
13477dd7cddfSDavid du Colombier<em>(x+w,y+h)</em>.  If <b><tt>width</tt></b>&nbsp;&lt;=&nbsp;0 or
13487dd7cddfSDavid du Colombierheight&nbsp;&lt;=&nbsp;0, <b><tt>fill_rectangle</tt></b> should return 0
13497dd7cddfSDavid du Colombierwithout drawing anything.
13507dd7cddfSDavid du Colombier
13517dd7cddfSDavid du Colombier<p>
13527dd7cddfSDavid du ColombierNote that <b><tt>fill_rectangle</tt></b> is the only non-optional procedure
13537dd7cddfSDavid du Colombierin the driver interface.
13547dd7cddfSDavid du Colombier</dl>
13557dd7cddfSDavid du Colombier
13563ff48bf5SDavid du Colombier<h4><a name="Bitmap_imaging"></a>Bitmap imaging</h4>
13577dd7cddfSDavid du Colombier
13587dd7cddfSDavid du Colombier<p>
13597dd7cddfSDavid du ColombierBitmap (or pixmap) images are stored in memory in a nearly standard way.
13607dd7cddfSDavid du ColombierThe first byte corresponds to <em>(0,0)</em> in the image coordinate
13617dd7cddfSDavid du Colombiersystem: bits (or polybit color values) are packed into it left to right.
13627dd7cddfSDavid du ColombierThere may be padding at the end of each scan line: the distance from one
13637dd7cddfSDavid du Colombierscan line to the next is always passed as an explicit argument.
13647dd7cddfSDavid du Colombier
13657dd7cddfSDavid du Colombier<dl>
1366*593dc095SDavid du Colombier<dt><b><tt>int (*copy_mono)(gx_device&nbsp;*,
13677dd7cddfSDavid du Colombierconst&nbsp;unsigned&nbsp;char&nbsp;*data, int&nbsp;data_x, int&nbsp;raster,
13687dd7cddfSDavid du Colombiergx_bitmap_id&nbsp;id, int&nbsp;x, int&nbsp;y, int&nbsp;width,
13697dd7cddfSDavid du Colombierint&nbsp;height, gx_color_index&nbsp;color0,
1370*593dc095SDavid du Colombiergx_color_index&nbsp;color1)</tt></b> <b><em>[OPTIONAL]</em></b>
13717dd7cddfSDavid du Colombier<dd>Copy a monochrome image (similar to the PostScript image operator).
13727dd7cddfSDavid du ColombierEach scan line is raster bytes wide.  Copying begins at
13737dd7cddfSDavid du Colombier(<b><tt>data_x</tt></b>,0) and transfers a rectangle of the given width and
13747dd7cddfSDavid du Colombierheight to the device at device coordinate <em>(x,y)</em>.  (If the transfer
13757dd7cddfSDavid du Colombiershould start at some non-zero y value in the data, the caller can adjust
13767dd7cddfSDavid du Colombierthe data address by the appropriate multiple of the raster.)  The copying
13777dd7cddfSDavid du Colombieroperation writes device color <b><tt>color0</tt></b> at each 0-bit, and
13787dd7cddfSDavid du Colombier<b><tt>color1</tt></b> at each 1-bit: if <b><tt>color0</tt></b> or
13797dd7cddfSDavid du Colombier<b><tt>color1</tt></b> is <b><tt>gx_no_color_index</tt></b>, the device
13807dd7cddfSDavid du Colombierpixel is unaffected if the image bit is 0 or 1 respectively.  If
13817dd7cddfSDavid du Colombier<b><tt>id</tt></b> is different from <b><tt>gx_no_bitmap_id</tt></b>, it
13827dd7cddfSDavid du Colombieridentifies the bitmap contents unambiguously; a call with the same
13837dd7cddfSDavid du Colombier<b><tt>id</tt></b> will always have the same <b><tt>data</tt></b>,
13847dd7cddfSDavid du Colombier<b><tt>raster</tt></b>, and data contents.
13857dd7cddfSDavid du Colombier
13867dd7cddfSDavid du Colombier<p>
13877dd7cddfSDavid du ColombierThis operation, with
13887dd7cddfSDavid du Colombier<b><tt>color0</tt></b>&nbsp;=&nbsp;<b><tt>gx_no_color_index</tt></b>, is
13897dd7cddfSDavid du Colombierthe workhorse for text display in Ghostscript, so implementing it
13907dd7cddfSDavid du Colombierefficiently is very important.
13917dd7cddfSDavid du Colombier</dl>
13927dd7cddfSDavid du Colombier
13937dd7cddfSDavid du Colombier<dl>
1394*593dc095SDavid du Colombier<dt><b><tt>int (*tile_rectangle)(gx_device&nbsp;*,
13957dd7cddfSDavid du Colombierconst&nbsp;gx_tile_bitmap&nbsp;*tile, int&nbsp;x, int&nbsp;y,
13967dd7cddfSDavid du Colombierint&nbsp;width, int&nbsp;height, gx_color_index&nbsp;color0,
1397*593dc095SDavid du Colombiergx_color_index&nbsp;color1, int&nbsp;phase_x, int&nbsp;phase_y)</tt></b>
13987dd7cddfSDavid du Colombier<b><em>[OPTIONAL] [OBSOLETE]</em></b>
13997dd7cddfSDavid du Colombier<dd>This procedure is still supported, but has been superseded by
14007dd7cddfSDavid du Colombier<b><tt>strip_tile_rectangle</tt></b>.  New drivers should implement
14017dd7cddfSDavid du Colombier<b><tt>strip_tile_rectangle</tt></b>; if they cannot cope with non-zero
14027dd7cddfSDavid du Colombiershift values, they should test for this explicitly and call the default
14037dd7cddfSDavid du Colombierimplementation (<b><tt>gx_default_strip_tile_rectangle</tt></b>) if
14047dd7cddfSDavid du Colombiershift&nbsp;!=&nbsp;0.  Clients should call
14057dd7cddfSDavid du Colombier<b><tt>strip_tile_rectangle</tt></b>, not <b><tt>tile_rectangle</tt></b>.
14067dd7cddfSDavid du Colombier</dl>
14077dd7cddfSDavid du Colombier
14087dd7cddfSDavid du Colombier<dl>
1409*593dc095SDavid du Colombier<dt><b><tt>int (*strip_tile_rectangle)(gx_device&nbsp;*,
14107dd7cddfSDavid du Colombierconst&nbsp;gx_strip_bitmap&nbsp;*tile, int&nbsp;x, int&nbsp;y,
14117dd7cddfSDavid du Colombierint&nbsp;width, int&nbsp;height, gx_color_index&nbsp;color0,
1412*593dc095SDavid du Colombiergx_color_index&nbsp;color1, int&nbsp;phase_x, int&nbsp;phase_y)</tt></b>
14137dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
14147dd7cddfSDavid du Colombier<dd>Tile a rectangle.  Tiling consists of doing multiple
14157dd7cddfSDavid du Colombier<b><tt>copy_mono</tt></b> operations to fill the rectangle with copies of
14167dd7cddfSDavid du Colombierthe tile.  The tiles are aligned with the device coordinate system, to
14177dd7cddfSDavid du Colombieravoid "seams".  Specifically, the (<b><tt>phase_x</tt></b>,
14187dd7cddfSDavid du Colombier<b><tt>phase_y</tt></b>) point of the tile is aligned with the origin of
14197dd7cddfSDavid du Colombierthe device coordinate system.  (Note that this is backwards from the
14207dd7cddfSDavid du ColombierPostScript definition of halftone phase.)  <b><tt>phase_x</tt></b> and
14217dd7cddfSDavid du Colombier<b><tt>phase_y</tt></b> are guaranteed to be in the range
14227dd7cddfSDavid du Colombier<em>[0..</em><b><tt>tile-&gt;width</tt></b><em>)</em> and
14237dd7cddfSDavid du Colombier<em>[0..</em><b><tt>tile-&gt;height</tt></b><em>)</em> respectively.
14247dd7cddfSDavid du Colombier
14257dd7cddfSDavid du Colombier<p>
14267dd7cddfSDavid du ColombierIf <b><tt>color0</tt></b> and <b><tt>color1</tt></b> are both
14277dd7cddfSDavid du Colombier<b><tt>gx_no_color_index</tt></b>, then the tile is a color pixmap, not a
14287dd7cddfSDavid du Colombierbitmap: see the next section.
14297dd7cddfSDavid du Colombier
14307dd7cddfSDavid du Colombier<p>
14317dd7cddfSDavid du ColombierThis operation is the workhorse for halftone filling in Ghostscript, so
14327dd7cddfSDavid du Colombierimplementing it efficiently for solid tiles (that is, where either
14337dd7cddfSDavid du Colombier<b><tt>color0</tt></b> and <b><tt>color1</tt></b> are both
14347dd7cddfSDavid du Colombier<b><tt>gx_no_color_index</tt></b>, for colored halftones, or neither one is
14357dd7cddfSDavid du Colombier<b><tt>gx_no_color_index</tt></b>, for monochrome halftones) is very
14367dd7cddfSDavid du Colombierimportant.
14377dd7cddfSDavid du Colombier</dl>
14387dd7cddfSDavid du Colombier
14393ff48bf5SDavid du Colombier<h4><a name="Pixmap_imaging"></a>Pixmap imaging</h4>
14407dd7cddfSDavid du Colombier
14417dd7cddfSDavid du Colombier<p>
14427dd7cddfSDavid du ColombierPixmaps are just like bitmaps, except that each pixel occupies more than
14437dd7cddfSDavid du Colombierone bit.  All the bits for each pixel are grouped together (this is
14447dd7cddfSDavid du Colombiersometimes called "chunky" or "Z" format).  For <b><tt>copy_color</tt></b>,
14457dd7cddfSDavid du Colombierthe number of bits per pixel is given by the
14467dd7cddfSDavid du Colombier<b><tt>color_info.depth</tt></b> parameter in the device structure: the
1447*593dc095SDavid du Colombierlegal values are 1, 2, 4, 8, 16, 24, 32, 40, 48, 56, or 64.  The pixel
1448*593dc095SDavid du Colombiervalues are device color codes (that is, whatever it is that
1449*593dc095SDavid du Colombier<b><tt>encode_color</tt></b> returns).
14507dd7cddfSDavid du Colombier
14517dd7cddfSDavid du Colombier<dl>
1452*593dc095SDavid du Colombier<dt><b><tt>int (*copy_color)(gx_device&nbsp;*,
14537dd7cddfSDavid du Colombierconst&nbsp;unsigned&nbsp;char&nbsp;*data, int&nbsp;data_x, int&nbsp;raster,
14547dd7cddfSDavid du Colombiergx_bitmap_id&nbsp;id, int&nbsp;x, int&nbsp;y, int&nbsp;width,
1455*593dc095SDavid du Colombierint&nbsp;height)</tt></b> <b><em>[OPTIONAL]</em></b>
14567dd7cddfSDavid du Colombier<dd>Copy a color image with multiple bits per pixel.  The raster is in
14577dd7cddfSDavid du Colombierbytes, but <b><tt>x</tt></b> and <b><tt>width</tt></b> are in pixels, not
14587dd7cddfSDavid du Colombierbits.  If <b><tt>id</tt></b> is different from
14597dd7cddfSDavid du Colombier<b><tt>gx_no_bitmap_id</tt></b>, it identifies the bitmap contents
14607dd7cddfSDavid du Colombierunambiguously; a call with the same <b><tt>id</tt></b> will always have the
14617dd7cddfSDavid du Colombiersame <b><tt>data</tt></b>, <b><tt>raster</tt></b>, and data contents.
14627dd7cddfSDavid du Colombier
14637dd7cddfSDavid du Colombier<p>
14647dd7cddfSDavid du ColombierWe do not provide a separate procedure for tiling with a pixmap; instead,
14657dd7cddfSDavid du Colombier<b><tt>tile_rectangle</tt></b> can also take colored tiles.  This is
14667dd7cddfSDavid du Colombierindicated by the <b><tt>color0</tt></b> and <b><tt>color1</tt></b>
14677dd7cddfSDavid du Colombierarguments' both being <b><tt>gx_no_color_index</tt></b>.  In this case, as
14687dd7cddfSDavid du Colombierfor <b><tt>copy_color</tt></b>, the <b><tt>raster</tt></b> and
14697dd7cddfSDavid du Colombier<b><tt>height</tt></b> in the "bitmap" are interpreted as for real bitmaps,
14707dd7cddfSDavid du Colombierbut the <b><tt>x</tt></b> and <b><tt>width</tt></b> are in pixels, not
14717dd7cddfSDavid du Colombierbits.
14727dd7cddfSDavid du Colombier</dl>
14737dd7cddfSDavid du Colombier
14743ff48bf5SDavid du Colombier<h4><a name="Compositing"></a>Compositing</h4>
14757dd7cddfSDavid du Colombier
14767dd7cddfSDavid du Colombier<p>
14777dd7cddfSDavid du ColombierIn addition to direct writing of opaque pixels, devices must also support
14787dd7cddfSDavid du Colombiercompositing.  Currently two kinds of compositing are defined
14797dd7cddfSDavid du Colombier(<b><tt>RasterOp</tt></b> and alpha-based), but more may be added in the
14807dd7cddfSDavid du Colombierfuture.
14817dd7cddfSDavid du Colombier
14827dd7cddfSDavid du Colombier<blockquote>
14837dd7cddfSDavid du Colombier<b><em>THIS AREA OF THE INTERFACE IS SOMEWHAT UNSTABLE: USE AT YOUR OWN
14847dd7cddfSDavid du ColombierRISK.</em></b>
14857dd7cddfSDavid du Colombier</blockquote>
14867dd7cddfSDavid du Colombier
14877dd7cddfSDavid du Colombier<dl>
1488*593dc095SDavid du Colombier<dt><b><tt>int (*copy_alpha)(gx_device&nbsp;*dev,
14897dd7cddfSDavid du Colombierconst&nbsp;unsigned&nbsp;char&nbsp;*data, int&nbsp;data_x, int&nbsp;raster,
14907dd7cddfSDavid du Colombiergx_bitmap_id&nbsp;id, int&nbsp;x, int&nbsp;y, int&nbsp;width,
1491*593dc095SDavid du Colombierint&nbsp;height, gx_color_index&nbsp;color, int&nbsp;depth)</tt></b>
14927dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
14937dd7cddfSDavid du Colombier<dd>This procedure is somewhat misnamed: it was added to the interface
14947dd7cddfSDavid du Colombierbefore we really understood alpha channel and compositing.
14957dd7cddfSDavid du Colombier
14967dd7cddfSDavid du Colombier<p>
14977dd7cddfSDavid du ColombierFill a given region with a given color modified by an individual alpha
14987dd7cddfSDavid du Colombiervalue for each pixel.  For each pixel, this is equivalent to
14997dd7cddfSDavid du Colombieralpha-compositing with a source pixel whose alpha value is obtained from
15007dd7cddfSDavid du Colombierthe pixmap (<b><tt>data</tt></b>, <b><tt>data_x</tt></b>, and
15017dd7cddfSDavid du Colombier<b><tt>raster</tt></b>) and whose color is the given color (which has
15027dd7cddfSDavid du Colombier<b><em>not</em></b> been premultiplied by the alpha value), using the Sover
15037dd7cddfSDavid du Colombierrule.  <b><tt>depth</tt></b>, the number of bits per alpha value, is either
15047dd7cddfSDavid du Colombier2 or 4, and in any case is always a value returned by a previous call on
15057dd7cddfSDavid du Colombierthe <b><tt>get_alpha_bits</tt></b> procedure.  Note that if
15067dd7cddfSDavid du Colombier<b><tt>get_alpha_bits</tt></b> always returns 1, this procedure will never
15077dd7cddfSDavid du Colombierbe called.
15087dd7cddfSDavid du Colombier</dl>
15097dd7cddfSDavid du Colombier
15107dd7cddfSDavid du Colombier<dl>
1511*593dc095SDavid du Colombier<dt><b><tt>int (*create_compositor)(dev_t&nbsp;*dev,
15127dd7cddfSDavid du Colombiergx_device_t&nbsp;**pcdev, const&nbsp;gs_composite_t&nbsp;*pcte,
1513*593dc095SDavid du Colombierconst&nbsp;gs_imager_state&nbsp;*pis, gs_memory_t&nbsp;*memory)</tt></b>
15147dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
15157dd7cddfSDavid du Colombier<dd>Create a new device (called a "compositing device" or "compositor")
15167dd7cddfSDavid du Colombierthat will composite data written to it with the device's existing data,
15177dd7cddfSDavid du Colombieraccording to the compositing function defined by <b><tt>*pcte</tt></b>.
15187dd7cddfSDavid du ColombierDevices will normally implement this in one of the following standard ways:
15197dd7cddfSDavid du Colombier
15207dd7cddfSDavid du Colombier<ul>
15217dd7cddfSDavid du Colombier<li>Devices that don't do any imaging and don't forward any imaging
15227dd7cddfSDavid du Colombieroperations (for example, the null device, the hit detection device, and the
15237dd7cddfSDavid du Colombierclipping list accumulation device) simply return themselves, which
15247dd7cddfSDavid du Colombiereffectively ignores the compositing function.
15257dd7cddfSDavid du Colombier
15267dd7cddfSDavid du Colombier<li>"Leaf" devices that do imaging and have no special optimizations for
15277dd7cddfSDavid du Colombiercompositing (for example, some memory devices) ask the
15287dd7cddfSDavid du Colombier<b><tt>gs_composite_t</tt></b> to create a default compositor.
15297dd7cddfSDavid du Colombier
15307dd7cddfSDavid du Colombier<li>Leaf devices that can implement some kinds of compositing operation
15317dd7cddfSDavid du Colombierefficiently (for example, monobit memory devices and RasterOp) inspect the
15327dd7cddfSDavid du Colombiertype and values of <b><tt>*pcte</tt></b> to determine whether it specifies
15337dd7cddfSDavid du Colombiersuch an operation: if so, they create a specialized compositor, and if not,
15347dd7cddfSDavid du Colombierthey ask the <b><tt>gs_composite_t</tt></b> to create a default compositor.
15357dd7cddfSDavid du Colombier</ul>
15367dd7cddfSDavid du Colombier
15377dd7cddfSDavid du Colombier<p>
15387dd7cddfSDavid du ColombierOther kinds of forwarding devices, which don't fall into any of these
15397dd7cddfSDavid du Colombiercategories, require special treatment.  In principle, what they do is ask
15407dd7cddfSDavid du Colombiertheir target to create a compositor, and then create and return a copy of
15417dd7cddfSDavid du Colombierthemselves with the target's new compositor as the target of the copy.
15427dd7cddfSDavid du ColombierThere is a possible default implementation of this approach: if the
15437dd7cddfSDavid du Colombieroriginal device was <b>D</b> with target <b>T</b>, and <b>T</b> creates a
15447dd7cddfSDavid du Colombiercompositor <b>C</b>, then the default implementation creates a device
15457dd7cddfSDavid du Colombier<b>F</b> that for each operation temporarily changes <b>D</b>'s target to
15467dd7cddfSDavid du Colombier<b>C</b>, forwards the operation to <b>D</b>, and then changes <b>D</b>'s
15477dd7cddfSDavid du Colombiertarget back to <b>T</b>.  However, the Ghostscript library currently only
15487dd7cddfSDavid du Colombiercreates a compositor with an imaging forwarding device as target in a few
15497dd7cddfSDavid du Colombierspecialized situations (banding, and bounding box computation), and these
15507dd7cddfSDavid du Colombierare handled as special cases.
15517dd7cddfSDavid du Colombier
15527dd7cddfSDavid du Colombier<p>
15537dd7cddfSDavid du ColombierNote that the compositor may have a different color space, color
15547dd7cddfSDavid du Colombierrepresentation, or bit depth from the device to which it is compositing.
15557dd7cddfSDavid du ColombierFor example, alpha-compositing devices use standard-format chunky color
15567dd7cddfSDavid du Colombiereven if the underlying device doesn't.
15577dd7cddfSDavid du Colombier
15587dd7cddfSDavid du Colombier<p>
15597dd7cddfSDavid du ColombierClosing a compositor frees all of its storage, including the compositor
15607dd7cddfSDavid du Colombieritself.  However, since the <b><tt>create_compositor</tt></b> call may
15617dd7cddfSDavid du Colombierreturn the same device, clients must check for this case, and only call the
15627dd7cddfSDavid du Colombierclose procedure if a separate device was created.
15637dd7cddfSDavid du Colombier</dl>
15647dd7cddfSDavid du Colombier
15657dd7cddfSDavid du Colombier<p>
15667dd7cddfSDavid du Colombier<font size="+1">
15677dd7cddfSDavid du Colombier<b><em>[strip_]copy_rop WILL BE SUPERSEDED BY COMPOSITORS</em></b>
15687dd7cddfSDavid du Colombier</font>
15697dd7cddfSDavid du Colombier
15707dd7cddfSDavid du Colombier<dl>
1571*593dc095SDavid du Colombier<dt><b><tt>int (*copy_rop)(gx_device&nbsp;*dev,
15727dd7cddfSDavid du Colombierconst&nbsp;byte&nbsp;*sdata, int&nbsp;sourcex, uint&nbsp;sraster,
15737dd7cddfSDavid du Colombiergx_bitmap_id&nbsp;id, const&nbsp;gx_color_index&nbsp;*scolors,
15747dd7cddfSDavid du Colombierconst&nbsp;gx_tile_bitmap&nbsp;*texture,
15757dd7cddfSDavid du Colombierconst&nbsp;gx_color_index&nbsp;*tcolors, int&nbsp;x, int&nbsp;y,
15767dd7cddfSDavid du Colombierint&nbsp;width, int&nbsp;height, int&nbsp;phase_x, int&nbsp;phase_y,
1577*593dc095SDavid du Colombierint&nbsp;command)</tt></b> <b><em>[OPTIONAL]</em></b>
15787dd7cddfSDavid du Colombier<dd>This procedure is still supported, but has been superseded by
15797dd7cddfSDavid du Colombier<b><tt>strip_copy_rop</tt></b>.  New drivers should implement
15807dd7cddfSDavid du Colombier<b><tt>strip_copy_rop</tt></b>; if they cannot cope with non-zero shift
15817dd7cddfSDavid du Colombiervalues in the texture, they should test for this explicitly and call the
15827dd7cddfSDavid du Colombierdefault implementation (<b><tt>gx_default_strip_copy_rop</tt></b>) if
15837dd7cddfSDavid du Colombiershift&nbsp;!=&nbsp;0.  Clients should call <b><tt>strip_copy_rop</tt></b>,
15847dd7cddfSDavid du Colombiernot <b><tt>copy_rop</tt></b>.
15857dd7cddfSDavid du Colombier</dl>
15867dd7cddfSDavid du Colombier
15877dd7cddfSDavid du Colombier<dl>
1588*593dc095SDavid du Colombier<dt><b><tt>int (*strip_copy_rop)(gx_device&nbsp;*dev,
15897dd7cddfSDavid du Colombierconst&nbsp;byte&nbsp;*sdata, int&nbsp;sourcex, uint&nbsp;sraster,
15907dd7cddfSDavid du Colombiergx_bitmap_id&nbsp;id, const&nbsp;gx_color_index&nbsp;*scolors,
15917dd7cddfSDavid du Colombierconst&nbsp;gx_strip_bitmap&nbsp;*texture,
15927dd7cddfSDavid du Colombierconst&nbsp;gx_color_index&nbsp;*tcolors, int&nbsp;x, int&nbsp;y,
15937dd7cddfSDavid du Colombierint&nbsp;width, int&nbsp;height, int&nbsp;phase_x, int&nbsp;phase_y,
1594*593dc095SDavid du Colombierint&nbsp;command)</tt></b> <b><em>[OPTIONAL]</em></b>
15957dd7cddfSDavid du Colombier<dd>Combine an optional source image <b>S</b> (as for
15967dd7cddfSDavid du Colombier<b><tt>copy_mono</tt></b> or <b><tt>copy_color</tt></b>) and an optional
15977dd7cddfSDavid du Colombiertexture <b>T</b> (a tile, as for <b><tt>tile_rectangle</tt></b>) with the
15987dd7cddfSDavid du Colombierexisting bitmap or pixmap <b>D</b> held by the driver, pixel by pixel,
15997dd7cddfSDavid du Colombierusing any 3-input Boolean operation as modified by "transparency" flags:
16007dd7cddfSDavid du Colombierschematically, set <b>D&nbsp;=&nbsp;f(D,S,T)</b>, computing <b>f</b> in RGB
16017dd7cddfSDavid du Colombierspace rather than using actual device pixel values.  <b>S</b> and <b>T</b>
16027dd7cddfSDavid du Colombiermay each (independently) be a solid color, a bitmap with "foreground" and
16037dd7cddfSDavid du Colombier"background" colors, or a pixmap.  This is a complex (and currently rather
16047dd7cddfSDavid du Colombierslow) operation.  The arguments are as follows:
16057dd7cddfSDavid du Colombier
16067dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
16077dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>dev</tt></b>
16087dd7cddfSDavid du Colombier	<td>&nbsp;
16097dd7cddfSDavid du Colombier	<td>the device, as for all driver procedures
16107dd7cddfSDavid du Colombier<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>
16117dd7cddfSDavid du Colombier	<td>&nbsp;
16127dd7cddfSDavid du Colombier	<td>specify <b>S</b>, <a href="#S_spec">see below</a>
16137dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>texture</tt></b>, <b><tt>tcolors</tt></b>
16147dd7cddfSDavid du Colombier	<td>&nbsp;
16157dd7cddfSDavid du Colombier	<td>specify <b>T</b>, <a href="#T_spec">see below</a>
16167dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>x</tt></b>, <b><tt>y</tt></b>, <b><tt>width</tt></b>, <b><tt>height</tt></b>
16177dd7cddfSDavid du Colombier	<td>&nbsp;
16187dd7cddfSDavid du Colombier	<td>as for the other copy and fill procedures
16197dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>phase_x</tt></b>, <b><tt>phase_y</tt></b>
16207dd7cddfSDavid du Colombier	<td>&nbsp;
16217dd7cddfSDavid du Colombier	<td>part of <b>T</b> specification, <a href="#T_spec">see below</a>
16227dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>command</tt></b>
16237dd7cddfSDavid du Colombier	<td>&nbsp;
16247dd7cddfSDavid du Colombier	<td><a href="#F_spec">see below</a>
16257dd7cddfSDavid du Colombier</table></blockquote>
16267dd7cddfSDavid du Colombier</dl>
16277dd7cddfSDavid du Colombier
16283ff48bf5SDavid du Colombier<h5><a name="S_spec"></a>The source specification S</h5>
16297dd7cddfSDavid du Colombier
16307dd7cddfSDavid du Colombier<p>
16317dd7cddfSDavid du ColombierAs noted above, the source <b>S</b> may be a solid color, a bitmap, or a
16327dd7cddfSDavid du Colombierpixmap.  If <b>S</b> is a solid color:
16337dd7cddfSDavid du Colombier
16347dd7cddfSDavid du Colombier<ul>
16357dd7cddfSDavid du Colombier<li><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>,
16367dd7cddfSDavid du Colombier<b><tt>sraster</tt></b>, and <b><tt>id</tt></b> are irrelevant.
16377dd7cddfSDavid du Colombier
16387dd7cddfSDavid du Colombier<li><b><tt>scolors</tt></b> points to two <b><tt>gx_color_index</tt></b>
16397dd7cddfSDavid du Colombiervalues; <b><tt>scolors[0]</tt></b> = <b><tt>scolors[1]</tt></b> = the
16407dd7cddfSDavid du Colombiercolor.
16417dd7cddfSDavid du Colombier</ul>
16427dd7cddfSDavid du Colombier
16437dd7cddfSDavid du Colombier<p>
16447dd7cddfSDavid du ColombierIf <b>S</b> is a bitmap:
16457dd7cddfSDavid du Colombier
16467dd7cddfSDavid du Colombier<ul>
16477dd7cddfSDavid du Colombier<li><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>,
16487dd7cddfSDavid du Colombier<b><tt>sraster</tt></b>, and <b><tt>id</tt></b> arguments are as for
16497dd7cddfSDavid du Colombier<b><tt>copy_mono</tt></b> or <b><tt>copy_color</tt></b>
16507dd7cddfSDavid du Colombier(<b><tt>data</tt></b>, <b><tt>data_x</tt></b>, <b><tt>raster</tt></b>,
16517dd7cddfSDavid du Colombier<b><tt>id</tt></b>), and specify a source bitmap.
16527dd7cddfSDavid du Colombier
16537dd7cddfSDavid du Colombier<li><b><tt>scolors</tt></b> points to two <b><tt>gx_color_index</tt></b>
16547dd7cddfSDavid du Colombiervalues; <b><tt>scolors[0]</tt></b> is the background color (the color
16557dd7cddfSDavid du Colombiercorresponding to 0-bits in the bitmap), <b><tt>scolors[1]</tt></b> is the
16567dd7cddfSDavid du Colombierforeground color (the color corresponding to 1-bits in the bitmap).
16577dd7cddfSDavid du Colombier</ul>
16587dd7cddfSDavid du Colombier
16597dd7cddfSDavid du Colombier<p>
16607dd7cddfSDavid du ColombierIf <b>S</b> is a pixmap:
16617dd7cddfSDavid du Colombier
16627dd7cddfSDavid du Colombier<ul>
16637dd7cddfSDavid du Colombier<li><b><tt>sdata</tt></b>, <b><tt>sourcex</tt></b>,
16647dd7cddfSDavid du Colombier<b><tt>sraster</tt></b>, and <b><tt>id</tt></b> arguments are as for
16657dd7cddfSDavid du Colombier<b><tt>copy_mono</tt></b> or <b><tt>copy_color</tt></b>
16667dd7cddfSDavid du Colombier(<b><tt>data</tt></b>, <b><tt>data_x</tt></b>, <b><tt>raster</tt></b>,
16677dd7cddfSDavid du Colombier<b><tt>id</tt></b>), and specify a source pixmap whose depth is the same as
16687dd7cddfSDavid du Colombierthe depth of the destination.
16697dd7cddfSDavid du Colombier
16707dd7cddfSDavid du Colombier<li><b><tt>scolors</tt></b> is <b><tt>NULL</tt></b>.
16717dd7cddfSDavid du Colombier</ul>
16727dd7cddfSDavid du Colombier
16737dd7cddfSDavid du Colombier<p>
16747dd7cddfSDavid du ColombierNote that if the source is a bitmap with background=0 and foreground=1, and
16757dd7cddfSDavid du Colombierthe destination is 1 bit deep, then the source can be treated as a pixmap
16767dd7cddfSDavid du Colombier(scolors=<b><tt>NULL</tt></b>).
16777dd7cddfSDavid du Colombier
16783ff48bf5SDavid du Colombier<h5><a name="T_spec"></a>The texture specification T</h5>
16797dd7cddfSDavid du Colombier
16807dd7cddfSDavid du Colombier<p>
16817dd7cddfSDavid du ColombierSimilar to the source, the texture <b>T</b> may be a solid color, a bitmap,
16827dd7cddfSDavid du Colombieror a pixmap.  If <b>T</b> is a solid color:
16837dd7cddfSDavid du Colombier
16847dd7cddfSDavid du Colombier<ul>
16857dd7cddfSDavid du Colombier<li>The texture pointer is irrelevant.
16867dd7cddfSDavid du Colombier
16877dd7cddfSDavid du Colombier<li><b><tt>tcolors</tt></b> points to two <b><tt>gx_color_index</tt></b>
16887dd7cddfSDavid du Colombiervalues; <b><tt>tcolors[0]</tt></b> = <b><tt>tcolors[1]</tt></b> = the
16897dd7cddfSDavid du Colombiercolor.
16907dd7cddfSDavid du Colombier</ul>
16917dd7cddfSDavid du Colombier
16927dd7cddfSDavid du Colombier<p>
16937dd7cddfSDavid du ColombierIf <b>T</b> is a bitmap:
16947dd7cddfSDavid du Colombier
16957dd7cddfSDavid du Colombier<ul>
16967dd7cddfSDavid du Colombier<li>The texture argument points to a <b><tt>gx_tile_bitmap</tt></b>, as for
16977dd7cddfSDavid du Colombierthe <b><tt>tile_rectangle</tt></b> procedure.  Similarly,
16987dd7cddfSDavid du Colombier<b><tt>phase_x</tt></b> and <b><tt>phase_y</tt></b> specify the offset of
16997dd7cddfSDavid du Colombierthe texture relative to the device coordinate system origin, again as for
17007dd7cddfSDavid du Colombier<b><tt>tile_rectangle</tt></b>.  The tile is a bitmap (1 bit per pixel).
17017dd7cddfSDavid du Colombier
17027dd7cddfSDavid du Colombier<li><b><tt>tcolors</tt></b> points to two <b><tt>gx_color_index</tt></b>
17037dd7cddfSDavid du Colombiervalues; <b><tt>tcolors[0]</tt></b> is the background color (the color
17047dd7cddfSDavid du Colombiercorresponding to 0-bits in the bitmap), <b><tt>tcolors[1]</tt></b> is the
17057dd7cddfSDavid du Colombierforeground color (the color corresponding to 1-bits in the bitmap).
17067dd7cddfSDavid du Colombier</ul>
17077dd7cddfSDavid du Colombier
17087dd7cddfSDavid du Colombier<p>
17097dd7cddfSDavid du ColombierIf <b>T</b> is a pixmap:
17107dd7cddfSDavid du Colombier
17117dd7cddfSDavid du Colombier<ul>
17127dd7cddfSDavid du Colombier<li>The texture argument points to a <b><tt>gx_tile_bitmap</tt></b> whose
17137dd7cddfSDavid du Colombierdepth is the same as the depth of the destination.
17147dd7cddfSDavid du Colombier
17157dd7cddfSDavid du Colombier<li>tcolors is <b><tt>NULL</tt></b>.
17167dd7cddfSDavid du Colombier</ul>
17177dd7cddfSDavid du Colombier
17187dd7cddfSDavid du Colombier<p>
17197dd7cddfSDavid du ColombierAgain, if the texture is a bitmap with background=0 and foreground=1, and
17207dd7cddfSDavid du Colombierthe destination depth is 1, the texture bitmap can be treated as a pixmap
17217dd7cddfSDavid du Colombier(tcolors=<b><tt>NULL</tt></b>).
17227dd7cddfSDavid du Colombier
17237dd7cddfSDavid du Colombier<p>
17247dd7cddfSDavid du ColombierNote that while a source bitmap or pixmap has the same width and height as
17257dd7cddfSDavid du Colombierthe destination, a texture bitmap or pixmap has its own width and height
17267dd7cddfSDavid du Colombierspecified in the <b><tt>gx_tile_bitmap</tt></b> structure, and is
17277dd7cddfSDavid du Colombierreplicated or clipped as needed.
17287dd7cddfSDavid du Colombier
17293ff48bf5SDavid du Colombier<h5><a name="F_spec"></a>The function specification f</h5>
17307dd7cddfSDavid du Colombier
17317dd7cddfSDavid du Colombier<p>
17327dd7cddfSDavid du Colombier"Command" indicates the raster operation and transparency as follows:
17337dd7cddfSDavid du Colombier
17347dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
17357dd7cddfSDavid du Colombier<tr valign=bottom>
17367dd7cddfSDavid du Colombier	<th>Bits
17377dd7cddfSDavid du Colombier	<td>&nbsp;
17387dd7cddfSDavid du Colombier	<td>&nbsp;
17397dd7cddfSDavid du Colombier<tr valign=top>	<td>7-0
17407dd7cddfSDavid du Colombier	<td>&nbsp;
17417dd7cddfSDavid du Colombier	<td>raster op
17427dd7cddfSDavid du Colombier<tr valign=top>	<td>8
17437dd7cddfSDavid du Colombier	<td>&nbsp;
17447dd7cddfSDavid du Colombier	<td>0 if source opaque, 1 if source transparent
17457dd7cddfSDavid du Colombier<tr valign=top>	<td>9
17467dd7cddfSDavid du Colombier	<td>&nbsp;
17477dd7cddfSDavid du Colombier	<td>0 if texture opaque, 1 if texture transparent
17487dd7cddfSDavid du Colombier<tr valign=top>	<td>?-10
17497dd7cddfSDavid du Colombier	<td>&nbsp;
17507dd7cddfSDavid du Colombier	<td>unused, must be 0
17517dd7cddfSDavid du Colombier</table></blockquote>
17527dd7cddfSDavid du Colombier
17537dd7cddfSDavid du Colombier<p>
17547dd7cddfSDavid du ColombierThe raster operation follows the Microsoft and H-P specification.  It is an
17557dd7cddfSDavid du Colombier8-element truth table that specifies the output value for each of the
17567dd7cddfSDavid du Colombierpossible 2&times;2&times;2 input values as follows:
17577dd7cddfSDavid du Colombier
17587dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
17597dd7cddfSDavid du Colombier<tr valign=bottom>
17607dd7cddfSDavid du Colombier	<th>Bit
17617dd7cddfSDavid du Colombier	<td>&nbsp;
17627dd7cddfSDavid du Colombier	<th>Texture
17637dd7cddfSDavid du Colombier	<td>&nbsp;
17647dd7cddfSDavid du Colombier	<th>Source
17657dd7cddfSDavid du Colombier	<td>&nbsp;
17667dd7cddfSDavid du Colombier	<th>Destination
17677dd7cddfSDavid du Colombier<tr>	<td colspan=7><hr>
17687dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>7
17697dd7cddfSDavid du Colombier	<td>&nbsp;
17707dd7cddfSDavid du Colombier	<td align=center>1
17717dd7cddfSDavid du Colombier	<td>&nbsp;
17727dd7cddfSDavid du Colombier	<td align=center>1
17737dd7cddfSDavid du Colombier	<td>&nbsp;
17747dd7cddfSDavid du Colombier	<td align=center>1
17757dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>6
17767dd7cddfSDavid du Colombier	<td>&nbsp;
17777dd7cddfSDavid du Colombier	<td align=center>1
17787dd7cddfSDavid du Colombier	<td>&nbsp;
17797dd7cddfSDavid du Colombier	<td align=center>1
17807dd7cddfSDavid du Colombier	<td>&nbsp;
17817dd7cddfSDavid du Colombier	<td align=center>0
17827dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>5
17837dd7cddfSDavid du Colombier	<td>&nbsp;
17847dd7cddfSDavid du Colombier	<td align=center>1
17857dd7cddfSDavid du Colombier	<td>&nbsp;
17867dd7cddfSDavid du Colombier	<td align=center>0
17877dd7cddfSDavid du Colombier	<td>&nbsp;
17887dd7cddfSDavid du Colombier	<td align=center>1
17897dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>4
17907dd7cddfSDavid du Colombier	<td>&nbsp;
17917dd7cddfSDavid du Colombier	<td align=center>1
17927dd7cddfSDavid du Colombier	<td>&nbsp;
17937dd7cddfSDavid du Colombier	<td align=center>0
17947dd7cddfSDavid du Colombier	<td>&nbsp;
17957dd7cddfSDavid du Colombier	<td align=center>0
17967dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>3
17977dd7cddfSDavid du Colombier	<td>&nbsp;
17987dd7cddfSDavid du Colombier	<td align=center>0
17997dd7cddfSDavid du Colombier	<td>&nbsp;
18007dd7cddfSDavid du Colombier	<td align=center>1
18017dd7cddfSDavid du Colombier	<td>&nbsp;
18027dd7cddfSDavid du Colombier	<td align=center>1
18037dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>2
18047dd7cddfSDavid du Colombier	<td>&nbsp;
18057dd7cddfSDavid du Colombier	<td align=center>0
18067dd7cddfSDavid du Colombier	<td>&nbsp;
18077dd7cddfSDavid du Colombier	<td align=center>1
18087dd7cddfSDavid du Colombier	<td>&nbsp;
18097dd7cddfSDavid du Colombier	<td align=center>0
18107dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>1
18117dd7cddfSDavid du Colombier	<td>&nbsp;
18127dd7cddfSDavid du Colombier	<td align=center>0
18137dd7cddfSDavid du Colombier	<td>&nbsp;
18147dd7cddfSDavid du Colombier	<td align=center>0
18157dd7cddfSDavid du Colombier	<td>&nbsp;
18167dd7cddfSDavid du Colombier	<td align=center>1
18177dd7cddfSDavid du Colombier<tr valign=top>	<td align=center>0
18187dd7cddfSDavid du Colombier	<td>&nbsp;
18197dd7cddfSDavid du Colombier	<td align=center>0
18207dd7cddfSDavid du Colombier	<td>&nbsp;
18217dd7cddfSDavid du Colombier	<td align=center>0
18227dd7cddfSDavid du Colombier	<td>&nbsp;
18237dd7cddfSDavid du Colombier	<td align=center>0
18247dd7cddfSDavid du Colombier</table></blockquote>
18257dd7cddfSDavid du Colombier
18267dd7cddfSDavid du Colombier<p>
18277dd7cddfSDavid du ColombierTransparency affects the output in the following way. A source or texture
18287dd7cddfSDavid du Colombierpixel is considered transparent if its value is all 1s (for instance, 1 for
18297dd7cddfSDavid du Colombierbitmaps, <tt>0xffffff</tt> for 24-bit RGB pixmaps) <b><em>and</em></b> the
18307dd7cddfSDavid du Colombiercorresponding transparency bit is set in the command. For each pixel, the
18317dd7cddfSDavid du Colombierresult of the Boolean operation is written into the destination iff neither
1832*593dc095SDavid du Colombierthe source nor the texture pixel is transparent. (Note that the HP
18337dd7cddfSDavid du ColombierRasterOp specification, on which this is based, specifies that if the
18347dd7cddfSDavid du Colombiersource and texture are both all 1s and the command specifies transparent
18357dd7cddfSDavid du Colombiersource and opaque texture, the result <b><em>should</em></b> be written in
18367dd7cddfSDavid du Colombierthe output. We think this is an error in the documentation.)
18377dd7cddfSDavid du Colombier
18383ff48bf5SDavid du Colombier<h5><a name="Compositing_notes"></a>Notes</h5>
18397dd7cddfSDavid du Colombier
18407dd7cddfSDavid du Colombier<p>
18417dd7cddfSDavid du Colombier<b><tt>copy_rop</tt></b> is defined to operate on pixels in RGB space,
1842*593dc095SDavid du Colombieragain following the HP and Microsoft specification. For devices that
18437dd7cddfSDavid du Colombierdon't use RGB (or gray-scale with black = 0, white = all 1s) as their
18447dd7cddfSDavid du Colombiernative color representation, the implementation of <b><tt>copy_rop</tt></b>
18457dd7cddfSDavid du Colombiermust convert to RGB or gray space, do the operation, and convert back (or
18467dd7cddfSDavid du Colombierdo the equivalent of this). Here are the <b><tt>copy_rop</tt></b>
18477dd7cddfSDavid du Colombierequivalents of the most important previous imaging calls. We assume the
18487dd7cddfSDavid du Colombierdeclaration:
18497dd7cddfSDavid du Colombier
18507dd7cddfSDavid du Colombier<blockquote><b><tt>
18517dd7cddfSDavid du Colombierstatic const gx_color_index white2[2] = { 1, 1 };
18527dd7cddfSDavid du Colombier</tt></b></blockquote>
18537dd7cddfSDavid du Colombier
18547dd7cddfSDavid du Colombier<p>
18557dd7cddfSDavid du ColombierNote that <b><tt>rop3_S</tt></b> may be replaced by any other Boolean operation.
18567dd7cddfSDavid du ColombierFor monobit devices, we assume that black = 1.
18577dd7cddfSDavid du Colombier
18583ff48bf5SDavid du Colombier<blockquote>
18597dd7cddfSDavid du Colombier<pre>/* For all devices: */
18607dd7cddfSDavid du Colombier(*fill_rectangle)(dev, x, y, w, h, color) ==&gt;
18617dd7cddfSDavid du Colombier
18627dd7cddfSDavid du Colombier        { gx_color_index colors[2];
18637dd7cddfSDavid du Colombier          colors[0] = colors[1] = color;
18647dd7cddfSDavid du Colombier          (*dev_proc(dev, copy_rop))(dev, NULL, 0, 0, gx_no_bitmap_id, colors,
18657dd7cddfSDavid du Colombier                                     NULL, colors /*irrelevant*/,
18667dd7cddfSDavid du Colombier                                     x, y, w, h, 0, 0, rop3_S);
18677dd7cddfSDavid du Colombier        }
18687dd7cddfSDavid du Colombier
18697dd7cddfSDavid du Colombier/* For black-and-white devices only: */
18707dd7cddfSDavid du Colombier(*copy_mono)(dev, base, sourcex, sraster, id,
18717dd7cddfSDavid du Colombier             x, y, w, h, (gx_color_index)0, (gx_color_index)1) ==&gt;
18727dd7cddfSDavid du Colombier
18737dd7cddfSDavid du Colombier        (*dev_proc(dev, copy_rop))(dev, base, sourcex, sraster, id, NULL,
18747dd7cddfSDavid du Colombier                                   NULL, white2 /*irrelevant*/,
18757dd7cddfSDavid du Colombier                                   x, y, w, h, 0, 0, rop3_S);
18767dd7cddfSDavid du Colombier
18777dd7cddfSDavid du Colombier/* For color devices, where neither color0 nor color1 is gx_no_color_index: */
18787dd7cddfSDavid du Colombier(*copy_mono)(dev, base, sourcex, sraster, id,
18797dd7cddfSDavid du Colombier             x, y, w, h, color0, color1) ==&gt;
18807dd7cddfSDavid du Colombier
18817dd7cddfSDavid du Colombier        { gx_color_index colors[2];
18827dd7cddfSDavid du Colombier          colors[0] = color0, colors[1] = color1;
18837dd7cddfSDavid du Colombier          (*dev_proc(dev, copy_rop))(dev, base, sourcex, sraster, id, colors,
18847dd7cddfSDavid du Colombier                                     NULL, white2 /*irrelevant*/,
18857dd7cddfSDavid du Colombier                                     x, y, w, h, 0, 0, rop3_S);
18867dd7cddfSDavid du Colombier        }
18877dd7cddfSDavid du Colombier
18887dd7cddfSDavid du Colombier/* For black-and-white devices only: */
18897dd7cddfSDavid du Colombier(*copy_mono)(dev, base, sourcex, sraster, id,
18907dd7cddfSDavid du Colombier             x, y, w, h, gx_no_color_index, (gx_color_index)1) ==&gt;
18917dd7cddfSDavid du Colombier
18927dd7cddfSDavid du Colombier        (*dev_proc(dev, copy_rop))(dev, base, sourcex, sraster, id, NULL,
18937dd7cddfSDavid du Colombier                                   NULL, white2 /*irrelevant*/,
18947dd7cddfSDavid du Colombier                                   x, y, w, h, 0, 0,
18957dd7cddfSDavid du Colombier                                   rop3_S | lop_S_transparent);
18967dd7cddfSDavid du Colombier
18977dd7cddfSDavid du Colombier/* For all devices: */
18987dd7cddfSDavid du Colombier(*copy_color)(dev, base, sourcex, sraster, id,
18997dd7cddfSDavid du Colombier              x, y, w, h) ==&gt; [same as first copy_mono above]
19007dd7cddfSDavid du Colombier
19017dd7cddfSDavid du Colombier/* For black-and-white devices only: */
19027dd7cddfSDavid du Colombier(*tile_rectangle)(dev, tile, x, y, w, h,
19037dd7cddfSDavid du Colombier                  (gx_color_index)0, (gx_color_index)1, px, py) ==&gt;
19047dd7cddfSDavid du Colombier
19057dd7cddfSDavid du Colombier        (*dev_proc(dev, copy_rop))(dev, NULL, 0, 0, gx_no_bitmap_id,
19067dd7cddfSDavid du Colombier                                   white2 /*irrelevant*/,
19077dd7cddfSDavid du Colombier                                   tile, NULL,
19083ff48bf5SDavid du Colombier                                   x, y, w, h, px, py, rop3_T)
19093ff48bf5SDavid du Colombier</pre></blockquote>
19107dd7cddfSDavid du Colombier
19113ff48bf5SDavid du Colombier<h3><a name="Polygon_level_drawing"></a>Polygon-level drawing</h3>
19127dd7cddfSDavid du Colombier
19137dd7cddfSDavid du Colombier<p>
19147dd7cddfSDavid du ColombierIn addition to the pixel-level drawing operations that take integer device
19157dd7cddfSDavid du Colombiercoordinates and pure device colors, the driver interface includes
19167dd7cddfSDavid du Colombierhigher-level operations that draw polygons using fixed-point coordinates,
19177dd7cddfSDavid du Colombierpossibly halftoned colors, and possibly a non-default logical operation.
19187dd7cddfSDavid du Colombier
19197dd7cddfSDavid du Colombier<p>
19207dd7cddfSDavid du ColombierThe <b><tt>fill_</tt></b>* drawing operations all use the center-of-pixel
19217dd7cddfSDavid du Colombierrule: a pixel is colored iff its center falls within the polygonal region
19227dd7cddfSDavid du Colombierbeing filled.  If a pixel center <em>(X+0.5,Y+0.5)</em> falls exactly on
19237dd7cddfSDavid du Colombierthe boundary, the pixel is filled iff the boundary is horizontal and the
19247dd7cddfSDavid du Colombierfilled region is above it, or the boundary is not horizontal and the filled
19257dd7cddfSDavid du Colombierregion is to the right of it.
19267dd7cddfSDavid du Colombier
19277dd7cddfSDavid du Colombier<dl>
1928*593dc095SDavid du Colombier<dt><b><tt>int (*fill_trapezoid)(gx_device&nbsp;*dev, const&nbsp;
1929*593dc095SDavid du Colombiergs_fixed_edge&nbsp;*left, const&nbsp;gs_fixed_edge&nbsp;*right,
19303ff48bf5SDavid du Colombierfixed&nbsp;ybot, fixed&nbsp;ytop, bool&nbsp;swap_axes,
19317dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
1932*593dc095SDavid du Colombiergs_logical_operation_t&nbsp;lop)</tt></b> <b><em>[OPTIONAL]</em></b>
19333ff48bf5SDavid du Colombier<dd>Fill a trapezoid. The bottom and top edges are parallel to the x
19343ff48bf5SDavid du Colombieraxis, and are defined by <b><tt>ybot</tt></b> and <b><tt>ytop</tt></b>,
19353ff48bf5SDavid du Colombierrespectively.  The left and right edges are defined by <b><tt>left</tt></b>
1936*593dc095SDavid du Colombierand <b><tt>right</tt></b>.  Both of these represent lines (<b><tt>gs_fixed_edge</tt></b>
19373ff48bf5SDavid du Colombieris defined in <a href="../src/gxdevcli.h">gxdevcli.h</a> and consists
19383ff48bf5SDavid du Colombierof <b><tt>gs_fixed_point</tt></b> <b><tt>start</tt></b> and <b><tt>end</tt></b> points).
19393ff48bf5SDavid du ColombierThe y coordinates of these lines need not have any specific relation to
19403ff48bf5SDavid du Colombier<b><tt>ybot</tt></b> and <b><tt>ytop</tt></b>. The routine is defined this way so
19413ff48bf5SDavid du Colombierthat the filling algorithm can subdivide edges and still guarantee
19423ff48bf5SDavid du Colombierthat the exact same pixels will be filled. If
19433ff48bf5SDavid du Colombier<b><tt>swap_axes</tt></b> is set, the meanings of X and Y are
19447dd7cddfSDavid du Colombierinterchanged.
19457dd7cddfSDavid du Colombier</dl>
1946*593dc095SDavid du Colombier<dt><b><tt>int (*fill_parallelogram)(gx_device&nbsp;*dev,
19477dd7cddfSDavid du Colombierfixed&nbsp;px, fixed&nbsp;py, fixed&nbsp;ax, fixed&nbsp;ay, fixed&nbsp;bx,
19487dd7cddfSDavid du Colombierfixed&nbsp;by, const&nbsp;gx_drawing_color&nbsp;*pdcolor,
1949*593dc095SDavid du Colombiergs_logical_operation_t&nbsp;lop)</tt></b> <b><em>[OPTIONAL]</em></b>
19507dd7cddfSDavid du Colombier<dd>Fill a parallelogram whose corners are <em>(px,py)</em>,
19517dd7cddfSDavid du Colombier<em>(px+ax,py+ay)</em>, <em>(px+bx,py+by)</em>, and
19527dd7cddfSDavid du Colombier<em>(px+ax+bx,py+ay+by)</em>.  There are no constraints on the values of
19537dd7cddfSDavid du Colombierany of the parameters, so the parallelogram may have any orientation
19547dd7cddfSDavid du Colombierrelative to the coordinate axes.
1955*593dc095SDavid du Colombier
19567dd7cddfSDavid du Colombier
19577dd7cddfSDavid du Colombier<dl>
1958*593dc095SDavid du Colombier<dt><b><tt>int (*fill_triangle)(gx_device&nbsp;*dev, fixed&nbsp;px,
19597dd7cddfSDavid du Colombierfixed&nbsp;py, fixed&nbsp;ax, fixed&nbsp;ay, fixed&nbsp;bx, fixed&nbsp;by,
19607dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
1961*593dc095SDavid du Colombiergs_logical_operation_t&nbsp;lop)</tt></b> <b><em>[OPTIONAL]</em></b>
19627dd7cddfSDavid du Colombier<dd>Fill a triangle whose corners are <em>(px,py)</em>,
19637dd7cddfSDavid du Colombier<em>(px+ax,py+ay)</em>, and <em>(px+bx,py+by)</em>.
19647dd7cddfSDavid du Colombier</dl>
19657dd7cddfSDavid du Colombier
19667dd7cddfSDavid du Colombier<dl>
1967*593dc095SDavid du Colombier<dt><b><tt>int (*draw_thin_line)(gx_device&nbsp;*dev,
19687dd7cddfSDavid du Colombierfixed&nbsp;fx0, fixed&nbsp;fy0, fixed&nbsp;fx1, fixed&nbsp;fy1,
19697dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
1970*593dc095SDavid du Colombiergs_logical_operation_t&nbsp;lop)</tt></b> <b><em>[OPTIONAL]</em></b>
19717dd7cddfSDavid du Colombier<dd>Draw a one-pixel-wide line from <em>(fx0,fy0)</em> to
19727dd7cddfSDavid du Colombier<em>(fx1,fy1)</em>.
19737dd7cddfSDavid du Colombier</dl>
19747dd7cddfSDavid du Colombier
19757dd7cddfSDavid du Colombier<dl>
1976*593dc095SDavid du Colombier<dt><b><tt>int (*draw_line)(gx_device&nbsp;*dev, int&nbsp;x0, int&nbsp;y0,
1977*593dc095SDavid du Colombierint&nbsp;x1, int&nbsp;y1, gx_color_index&nbsp;color)</tt></b>
19787dd7cddfSDavid du Colombier<b><em>[OPTIONAL] [OBSOLETE]</em></b>
19797dd7cddfSDavid du Colombier<dd>This procedure is no longer used: it is replaced by the draw_thin_line
19807dd7cddfSDavid du Colombierprocedure.  However, still appears in the driver procedure vector for
19817dd7cddfSDavid du Colombierbackward compatibility.  It should never be called, and drivers should not
19827dd7cddfSDavid du Colombierimplement it.
19837dd7cddfSDavid du Colombier</dl>
19847dd7cddfSDavid du Colombier
1985*593dc095SDavid du Colombier<h3><a name="Linear_color_drawing"></a>Linear color drawing</h3>
1986*593dc095SDavid du Colombier
1987*593dc095SDavid du Colombier<p>
1988*593dc095SDavid du ColombierLinear color functions allow fast high quality rendering of
1989*593dc095SDavid du Colombiershadings on continuous tone devices. They implement filling simple areas
1990*593dc095SDavid du Colombierwith a lineary varying color. These functions are not called if the device applies halftones,
1991*593dc095SDavid du Colombieror uses a non-separable or a non-linear color model.
1992*593dc095SDavid du Colombier
1993*593dc095SDavid du Colombier<dl>
1994*593dc095SDavid du Colombier<dt><b><tt> int (*fill_linear_color_triangle)
1995*593dc095SDavid du Colombier  (dev_t *dev, const gs_fill_attributes *fa,
1996*593dc095SDavid du Colombier	const gs_fixed_point *p0, const gs_fixed_point *p1,
1997*593dc095SDavid du Colombier	const gs_fixed_point *p2,
1998*593dc095SDavid du Colombier	const frac31 *c0, const frac31 *c1, const frac31 *c2)
1999*593dc095SDavid du Colombier</tt></b>
2000*593dc095SDavid du Colombier<b><em>[OPTIONAL]</em></b>
2001*593dc095SDavid du Colombier<dd>This function is the highest level one within the linear color function group.
2002*593dc095SDavid du ColombierIt fills a triangle with a linearly varying color.
2003*593dc095SDavid du ColombierArguments specify 3 points in the device space - vertices of a triangle, and their colors.
2004*593dc095SDavid du ColombierThe colors are represented as vectors of positive fractional numbers, each of which
2005*593dc095SDavid du Colombierrepresents a color component value in the interval <b><tt>[0,1]</tt></b>.
2006*593dc095SDavid du ColombierThe number of components in a vector in the number of color
2007*593dc095SDavid du Colombiercomponents in the device (process) color model.
2008*593dc095SDavid du Colombier<dd>
2009*593dc095SDavid du ColombierThe implementation fills entire triangle.
2010*593dc095SDavid du ColombierThe filling rule is same as for <a href="#Polygon_level_drawing">Polygon-level drawing</a>.
2011*593dc095SDavid du ColombierA color for each pixel within the triangle to be computed as a linear interpolation
2012*593dc095SDavid du Colombierof vertex colors.
2013*593dc095SDavid du Colombier<dd>
2014*593dc095SDavid du ColombierThe implementation may reject the request if the area or the color appears too complex
2015*593dc095SDavid du Colombierfor filling in a single action. For doing that the implementation returns 0 and must not
2016*593dc095SDavid du Colombierpaint any pixel. In this case the graphics library will perform a subdivision of the area
2017*593dc095SDavid du Colombierinto smaller triangles and call the function again with smaller areas.
2018*593dc095SDavid du Colombier<dd>
2019*593dc095SDavid du Colombier<b><em>Important note :</em></b> Do not try to decompose the area within
2020*593dc095SDavid du Colombierthe implementation of <b><tt> fill_linear_color_triangle </tt></b>, because
2021*593dc095SDavid du Colombierit can break the plane coverage contiguity and cause a dropout.
2022*593dc095SDavid du ColombierInstead that request graphics library to perform the decomposition.
2023*593dc095SDavid du ColombierThe graphics libary is smart enough to do that properly.
2024*593dc095SDavid du Colombier<dd>
2025*593dc095SDavid du Colombier<b><em>Important note :</em></b>
2026*593dc095SDavid du ColombierThe implementation must handle a special case, when only 2 colors are specified.
2027*593dc095SDavid du ColombierIt happens if <b><tt>p3</tt></b> one is <b><tt>NULL</tt></b>.
2028*593dc095SDavid du ColombierThis means that the color does not depend on the X coordinate,
2029*593dc095SDavid du Colombieri.e. it forms a linear gradient along the Y axis.
2030*593dc095SDavid du ColombierThe implementation must not reject (return 0) such cases.
2031*593dc095SDavid du Colombier<dd>
2032*593dc095SDavid du Colombier<b><em>Important note :</em></b>The device color component
2033*593dc095SDavid du Colombiervalue 1 may be represented with several hexadecimal values :
2034*593dc095SDavid du Colombier<b><tt>0x7FFF0000</tt></b>, <b><tt>0x7FFFF000</tt></b>, <b><tt>0x7FFFFF00</tt></b>, etc.,
2035*593dc095SDavid du Colombierbecause the precision here exceeds the color precision of the device.
2036*593dc095SDavid du ColombierTo convert a <b><tt>frac31</tt></b> value into a device color component value,
2037*593dc095SDavid du Colombierfist drop (ignore) the sign bit, then drop least significant bits -
2038*593dc095SDavid du Colombierso many ones as you need to fit the device color precision.
2039*593dc095SDavid du Colombier<dd>
2040*593dc095SDavid du Colombier<b><em>Important note :</em></b> The <b><tt>fa</tt></b> argument may contain
2041*593dc095SDavid du Colombierthe <b><tt>swap_axes</tt></b> bit set. In this case the implementation must swap (transpoze)
2042*593dc095SDavid du Colombier<b><tt>X</tt></b> and <b><tt>Y</tt></b> axes.
2043*593dc095SDavid du Colombier<dd>
2044*593dc095SDavid du Colombier<b><em>Important note :</em></b> The implementation must not paint outside the
2045*593dc095SDavid du Colombierclipping rectangle specified in the <b><tt>fa</tt></b> argument.
2046*593dc095SDavid du ColombierIf <b><tt>fa->swap_axes</tt></b> is true, the clipping rectangle is transposed.
2047*593dc095SDavid du Colombier<dd>
2048*593dc095SDavid du ColombierSee <b><tt> gx_default_fill_linear_color_triangle </tt></b>
2049*593dc095SDavid du Colombierin <b><tt>gdevddrw.c</tt></b> as a sample code.
2050*593dc095SDavid du Colombier</dl>
2051*593dc095SDavid du Colombier
2052*593dc095SDavid du Colombier
2053*593dc095SDavid du Colombier<dl>
2054*593dc095SDavid du Colombier<dt><b><tt> int (*fill_linear_color_trapezoid)
2055*593dc095SDavid du Colombier  (dev_t *dev, const gs_fill_attributes *fa,
2056*593dc095SDavid du Colombier	const gs_fixed_point *p0, const gs_fixed_point *p1,
2057*593dc095SDavid du Colombier	const gs_fixed_point *p2, const gs_fixed_point *p3,
2058*593dc095SDavid du Colombier	const frac31 *c0, const frac31 *c1,
2059*593dc095SDavid du Colombier	const frac31 *c2, const frac31 *c2)
2060*593dc095SDavid du Colombier</tt></b>
2061*593dc095SDavid du Colombier<b><em>[OPTIONAL]</em></b>
2062*593dc095SDavid du Colombier<dd>This function is a lower level one within the linear color function group.
2063*593dc095SDavid du ColombierThe default implementation of <b><tt> fill_linear_color_triangle </tt></b>
2064*593dc095SDavid du Colombiercalls this function 1-2 times per triangle. Besides that,
2065*593dc095SDavid du Colombierthis function may be called by the graphics library for other special cases,
2066*593dc095SDavid du Colombierwhen a decomposition into triangles appears undiserable.
2067*593dc095SDavid du Colombier<dd>
2068*593dc095SDavid du ColombierRather the prototype can specify a bilinear color,
2069*593dc095SDavid du Colombierwe assume that the implementation handles linear colors only.
2070*593dc095SDavid du ColombierThis means that the implementation can ignore any of <b><tt> c0, c1, c2, c3 </tt></b>.
2071*593dc095SDavid du ColombierThe graphics library takes a special care of the color linearity
2072*593dc095SDavid du Colombierwhen calling this function. The reason for passing all 4 color arguments
2073*593dc095SDavid du Colombieris to avoid color precision problems.
2074*593dc095SDavid du Colombier<dd>
2075*593dc095SDavid du ColombierSimilarly to <b><tt> fill_linear_color_triangle </tt></b>,
2076*593dc095SDavid du Colombierthis function may be called with only 2 colors, and may reject too comple areas.
2077*593dc095SDavid du ColombierAll those important notes are applicable here.
2078*593dc095SDavid du Colombier<dd>
2079*593dc095SDavid du ColombierA sample code may be found in in <b><tt>gxdtfill.h</tt></b>, rather it's a kind of complicated.
2080*593dc095SDavid du ColombierA linear color function is generated from it as <b><tt> gx_fill_trapezoid_ns_lc </tt></b>
2081*593dc095SDavid du Colombierwith the following template parametres :
2082*593dc095SDavid du Colombier
2083*593dc095SDavid du Colombier<pre>
2084*593dc095SDavid du Colombier#define LINEAR_COLOR 1
2085*593dc095SDavid du Colombier#define EDGE_TYPE gs_linear_color_edge
2086*593dc095SDavid du Colombier#define FILL_ATTRS const gs_fill_attributes *
2087*593dc095SDavid du Colombier#define CONTIGUOUS_FILL 0
2088*593dc095SDavid du Colombier#define SWAP_AXES 0
2089*593dc095SDavid du Colombier#define FILL_DIRECT 1
2090*593dc095SDavid du Colombier</pre>
2091*593dc095SDavid du ColombierSee the helplers <b><tt>init_gradient</tt></b>,
2092*593dc095SDavid du Colombier<b><tt>step_gradient</tt></b> (defined in in <b><tt>gdevddrw.c</tt></b>), how to manage colors.
2093*593dc095SDavid du ColombierSee <b><tt>check_gradient_overflow</tt></b>
2094*593dc095SDavid du Colombier(defined in in <b><tt>gdevddrw.c</tt></b>), as an example of an area
2095*593dc095SDavid du Colombierthat can't be painted in a single action due to 64-bits fixed overflows.
2096*593dc095SDavid du Colombier
2097*593dc095SDavid du Colombier</dl>
2098*593dc095SDavid du Colombier
2099*593dc095SDavid du Colombier<dl>
2100*593dc095SDavid du Colombier<dt><b><tt> int (*fill_linear_color_scanline)
2101*593dc095SDavid du Colombier      (dev_t *dev, const gs_fill_attributes *fa,
2102*593dc095SDavid du Colombier	int i, int j, int w,
2103*593dc095SDavid du Colombier	const frac31 *c0,
2104*593dc095SDavid du Colombier	const int32_t *c0_f,
2105*593dc095SDavid du Colombier	const int32_t *cg_num,
2106*593dc095SDavid du Colombier	int32_t cg_den)
2107*593dc095SDavid du Colombier</tt></b>
2108*593dc095SDavid du Colombier<b><em>[OPTIONAL]</em></b>
2109*593dc095SDavid du Colombier<dd>This function is the lowest level one within the linear color function group.
2110*593dc095SDavid du ColombierIt implements filling a scanline with a linearly varying color.
2111*593dc095SDavid du ColombierThe default implementation for <b><tt> fill_linear_color_trapezoid </tt></b>
2112*593dc095SDavid du Colombiercalls this function, and there are no other calls to it from the graphics libary.
2113*593dc095SDavid du ColombierThus if the device implements <b><tt> fill_linear_color_triangle </tt></b> and
2114*593dc095SDavid du Colombier<b><tt> fill_linear_color_trapezoid </tt></b> by own means,
2115*593dc095SDavid du Colombierthis function may be left unimplemented.
2116*593dc095SDavid du Colombier<dd>
2117*593dc095SDavid du Colombier<b><tt>i</tt></b> and <b><tt>j</tt></b> specify device coordinates (indices)
2118*593dc095SDavid du Colombierof the starting pixel of the scanline, <b><tt>w</tt></b> specifies the
2119*593dc095SDavid du Colombierwidth of the scanline, i.e. the number of pixels to be painted to the right from
2120*593dc095SDavid du Colombierthe starting pixel, including the starting pixel.
2121*593dc095SDavid du Colombier<dd>
2122*593dc095SDavid du Colombier<b><tt>c0</tt></b> specifies the color for the starting pixel
2123*593dc095SDavid du Colombieras a vector of fraction values, each of which represents
2124*593dc095SDavid du Colombiera color value in the interval <b><tt>[0,1]</tt></b>.
2125*593dc095SDavid du Colombier<dd>
2126*593dc095SDavid du Colombier<b><tt>c0_f</tt></b> specify a fraction part of the color for the starting pixel.
2127*593dc095SDavid du ColombierSee the formula below about using it.
2128*593dc095SDavid du Colombier<dd>
2129*593dc095SDavid du Colombier<b><tt>cg_num</tt></b> specify a numerator for the color gradient -
2130*593dc095SDavid du Colombiera vector of values in <b><tt>[-1,1]</tt></b>, each of which correspond to a color component.
2131*593dc095SDavid du Colombier<dd>
2132*593dc095SDavid du Colombier<b><tt>cg_den</tt></b> specify the denominator for the color gradient -
2133*593dc095SDavid du Colombiera value in <b><tt>[-1,1]</tt></b>.
2134*593dc095SDavid du Colombier<dd><p>
2135*593dc095SDavid du ColombierThe color for the pixel <b><tt>[i + k, j]</tt></b> to be computed like this :
2136*593dc095SDavid du Colombier<pre><b><tt>
2137*593dc095SDavid du Colombier         (double)(c0[n] + (c0_f[n] + cg_num[n] * k) / cg_den) / (1 ^ 31 - 1)
2138*593dc095SDavid du Colombier</tt></b></pre>
2139*593dc095SDavid du Colombier<dd>where <b><tt>0 <= k <= w </tt></b>, and <b><tt>n</tt></b> is a device color component index.
2140*593dc095SDavid du Colombier
2141*593dc095SDavid du Colombier<dd>
2142*593dc095SDavid du Colombier<b><em>Important note :</em></b> The <b><tt>fa</tt></b> argument may contain
2143*593dc095SDavid du Colombierthe <b><tt>swap_axes</tt></b> bit set. In this case the implementation must swap (transpose)
2144*593dc095SDavid du Colombier<b><tt>X</tt></b> and <b><tt>Y</tt></b> axes.
2145*593dc095SDavid du Colombier<dd>
2146*593dc095SDavid du Colombier<b><em>Important note :</em></b> The implementation must not paint outside the
2147*593dc095SDavid du Colombierclipping rectangle specified in the <b><tt>fa</tt></b> argument.
2148*593dc095SDavid du ColombierIf <b><tt>fa->swap_axes</tt></b> is true, the clipping rectangle is transposed.
2149*593dc095SDavid du Colombier<dd>
2150*593dc095SDavid du ColombierSee <b><tt> gx_default_fill_linear_color_scanline</tt></b>
2151*593dc095SDavid du Colombierin <b><tt>gdevdsha.c</tt></b> as a sample code.
2152*593dc095SDavid du Colombier</dl>
2153*593dc095SDavid du Colombier
2154*593dc095SDavid du Colombier
21553ff48bf5SDavid du Colombier<h3><a name="High_level_drawing"></a>High-level drawing</h3>
21567dd7cddfSDavid du Colombier
21577dd7cddfSDavid du Colombier<p>
21587dd7cddfSDavid du ColombierIn addition to the lower-level drawing operations described above, the
21597dd7cddfSDavid du Colombierdriver interface provides a set of high-level operations.  Normally these
21607dd7cddfSDavid du Colombierwill have their default implementation, which converts the high-level
21617dd7cddfSDavid du Colombieroperation to the low-level ones just described; however, drivers that
21627dd7cddfSDavid du Colombiergenerate high-level output formats such as CGM, or communicate with devices
21637dd7cddfSDavid du Colombierthat have firmware for higher-level operations such as polygon fills, may
21647dd7cddfSDavid du Colombierimplement these high-level operations directly.  For more details, please
21657dd7cddfSDavid du Colombierconsult the source code, specifically:
21667dd7cddfSDavid du Colombier
21677dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
21687dd7cddfSDavid du Colombier<tr valign=top>	<th align=left>Header
21697dd7cddfSDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;
21707dd7cddfSDavid du Colombier	<th align=left>Defines
21713ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gxpaint.h">gxpaint.h</a>
21727dd7cddfSDavid du Colombier	<td>&nbsp;
21737dd7cddfSDavid du Colombier	<td><b><tt>gx_fill_params</tt></b>, <b><tt>gx_stroke_params</tt></b>
21743ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gxfixed.h">gxfixed.h</a>
21757dd7cddfSDavid du Colombier	<td>&nbsp;
21767dd7cddfSDavid du Colombier	<td><b><tt>fixed</tt></b>, <b><tt>gs_fixed_point</tt></b> (used by
21777dd7cddfSDavid du Colombier	    <b><tt>gx_*_params</tt></b>)
21783ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gxistate.h">gxistate.h</a>
21797dd7cddfSDavid du Colombier	<td>&nbsp;
21807dd7cddfSDavid du Colombier	<td><b><tt>gs_imager_state</tt></b> (used by <b><tt>gx_*_params</tt></b>)
21813ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gxline.h">gxline.h</a>
21827dd7cddfSDavid du Colombier	<td>&nbsp;
21837dd7cddfSDavid du Colombier	<td><b><tt>gx_line_params</tt></b> (used by <b><tt>gs_imager_state</tt></b>)
21843ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gslparam.h">gslparam.h</a>
21857dd7cddfSDavid du Colombier	<td>&nbsp;
21867dd7cddfSDavid du Colombier	<td>line cap/join values (used by <b><tt>gx_line_params</tt></b>)
21873ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gxmatrix.h">gxmatrix.h</a>
21887dd7cddfSDavid du Colombier	<td>&nbsp;
21897dd7cddfSDavid du Colombier	<td><b><tt>gs_matrix_fixed</tt></b> (used by <b><tt>gs_imager_state</tt></b>)
21903ff48bf5SDavid du Colombier<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>
21917dd7cddfSDavid du Colombier	<td>&nbsp;
21927dd7cddfSDavid du Colombier	<td><b><tt>gx_path</tt></b>
21933ff48bf5SDavid du Colombier<tr valign=top>	<td><a href="../src/gxcpath.h">gxcpath.h</a>, <a href="../src/gzcpath.h">gzcpath.h</a>
21947dd7cddfSDavid du Colombier	<td>&nbsp;
21957dd7cddfSDavid du Colombier	<td><b><tt>gx_clip_path</tt></b>
21967dd7cddfSDavid du Colombier</table></blockquote>
21977dd7cddfSDavid du Colombier
21983ff48bf5SDavid du Colombier<p>
21993ff48bf5SDavid du ColombierFor a minimal example of how to implement the high-level drawing operations,
22003ff48bf5SDavid du Colombiersee <a href="../src/gdevtrac.c">gdevtrac.c</a>.
22013ff48bf5SDavid du Colombier
22023ff48bf5SDavid du Colombier<h4><a name="Paths"></a>Paths</h4>
22037dd7cddfSDavid du Colombier
22047dd7cddfSDavid du Colombier<dl>
2205*593dc095SDavid du Colombier<dt><b><tt>int (*fill_path)(gx_device&nbsp;*dev,
22063ff48bf5SDavid du Colombierconst&nbsp;gs_imager_state&nbsp;*pis, gx_path&nbsp;*ppath,
22077dd7cddfSDavid du Colombierconst&nbsp;gx_fill_params&nbsp;*params,
22087dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
2209*593dc095SDavid du Colombierconst&nbsp;gx_clip_path&nbsp;*pcpath)</tt></b> <b><em>[OPTIONAL]</em></b>
22107dd7cddfSDavid du Colombier<dd>Fill the given path, clipped by the given clip path, according to the
22117dd7cddfSDavid du Colombiergiven parameters, with the given color.  The clip path pointer may be
22127dd7cddfSDavid du Colombier<b><tt>NULL</tt></b>, meaning do not clip.
2213*593dc095SDavid du Colombier<dd>
2214*593dc095SDavid du ColombierThe implementation must paint the path with the specified device color,
2215*593dc095SDavid du Colombierwhich may be either a pure color, or a pattern. If the device can't
2216*593dc095SDavid du Colombierhandle non-pure colors, it should check the color type and
2217*593dc095SDavid du Colombiercall the default implementation gx_default_fill_path for cases,
2218*593dc095SDavid du Colombierwhich the device can't handle. The default implementation will perform
2219*593dc095SDavid du Colombiera subdivision of the area to be painted, and will
2220*593dc095SDavid du Colombiercall other device virtual functions (such as fill_linear_color_triangle)
2221*593dc095SDavid du Colombierwith simpler areas.
2222*593dc095SDavid du Colombier
22237dd7cddfSDavid du Colombier</dl>
22247dd7cddfSDavid du Colombier
22257dd7cddfSDavid du Colombier<dl>
2226*593dc095SDavid du Colombier<dt><b><tt>int (*stroke_path)(gx_device&nbsp;*dev,
22273ff48bf5SDavid du Colombierconst&nbsp;gs_imager_state&nbsp;*pis, gx_path&nbsp;*ppath,
22287dd7cddfSDavid du Colombierconst&nbsp;gx_stroke_params&nbsp;*params,
22297dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
2230*593dc095SDavid du Colombierconst&nbsp;gx_clip_path&nbsp;*pcpath)</tt></b> <b><em>[OPTIONAL]</em></b>
22317dd7cddfSDavid du Colombier<dd>Stroke the given path, clipped by the given clip path, according to the
22327dd7cddfSDavid du Colombiergiven parameters, with the given color.  The clip path pointer may be
22337dd7cddfSDavid du Colombier<b><tt>NULL</tt></b>, meaning not to clip.
22347dd7cddfSDavid du Colombier</dl>
22357dd7cddfSDavid du Colombier
22367dd7cddfSDavid du Colombier<dl>
2237*593dc095SDavid du Colombier<dt><b><tt>int (*fill_mask)(gx_device&nbsp;*dev,
22387dd7cddfSDavid du Colombierconst&nbsp;byte&nbsp;*data, int&nbsp;data_x, int&nbsp;raster,
22397dd7cddfSDavid du Colombiergx_bitmap_id&nbsp;id, int&nbsp;x, int&nbsp;y, int&nbsp;width,
22407dd7cddfSDavid du Colombierint&nbsp;height, const&nbsp;gx_drawing_color&nbsp;*pdcolor, int&nbsp;depth,
2241*593dc095SDavid du Colombierint&nbsp;command, const&nbsp;gx_clip_path&nbsp;*pcpath)</tt></b>
22427dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
22437dd7cddfSDavid du Colombier<dd>Color the 1-bits in the given mask (or according to the alpha values,
22447dd7cddfSDavid du Colombierif <b><tt>depth</tt></b>&nbsp;&gt;&nbsp;1), clipped by the given clip path,
22457dd7cddfSDavid du Colombierwith the given color and logical operation.  The clip path pointer may be
22467dd7cddfSDavid du Colombier<b><tt>NULL</tt></b>, meaning do not clip.  The parameters
22477dd7cddfSDavid du Colombier<b><tt>data</tt></b>, ..., <b><tt>height</tt></b> are as for
22487dd7cddfSDavid du Colombier<b><tt>copy_mono</tt></b>; depth is as for <b><tt>copy_alpha</tt></b>;
22497dd7cddfSDavid du Colombiercommand is as for <b><tt>copy_rop</tt></b>.
22507dd7cddfSDavid du Colombier</dl>
22517dd7cddfSDavid du Colombier
22523ff48bf5SDavid du Colombier<h4><a name="Images"></a>Images</h4>
22537dd7cddfSDavid du Colombier
22547dd7cddfSDavid du Colombier<p>
22557dd7cddfSDavid du ColombierSimilar to the high-level interface for fill and stroke graphics, a high-level
22567dd7cddfSDavid du Colombierinterface exists for bitmap images.  The procedures in this part of the
22577dd7cddfSDavid du Colombierinterface are optional.
22587dd7cddfSDavid du Colombier
22597dd7cddfSDavid du Colombier<p>
22607dd7cddfSDavid du ColombierBitmap images come in a variety of types, corresponding closely (but not
22617dd7cddfSDavid du Colombierprecisely) to the PostScript ImageTypes.  The generic or common part of all
22627dd7cddfSDavid du Colombierbitmap images is defined by:
22637dd7cddfSDavid du Colombier
22647dd7cddfSDavid du Colombier<blockquote>
22657dd7cddfSDavid du Colombier<pre>typedef struct {
22667dd7cddfSDavid du Colombier	const gx_image_type_t *type;
22677dd7cddfSDavid du Colombier        gs_matrix ImageMatrix;
22687dd7cddfSDavid du Colombier} gs_image_common_t;</pre>
22697dd7cddfSDavid du Colombier</blockquote>
22707dd7cddfSDavid du Colombier
22717dd7cddfSDavid du Colombier<p>
22727dd7cddfSDavid du ColombierBitmap images that supply data (all image types except
22737dd7cddfSDavid du Colombier<b><tt>image_type_from_device</tt></b> (2)) are defined by:
22747dd7cddfSDavid du Colombier
22757dd7cddfSDavid du Colombier<blockquote>
22767dd7cddfSDavid du Colombier<pre>#define gs_image_max_components 5
22777dd7cddfSDavid du Colombiertypedef struct {
22787dd7cddfSDavid du Colombier        &lt;&lt; gs_image_common_t &gt;&gt;
22797dd7cddfSDavid du Colombier        int Width;
22807dd7cddfSDavid du Colombier        int Height;
22817dd7cddfSDavid du Colombier        int BitsPerComponent;
22827dd7cddfSDavid du Colombier        float Decode[gs_image_max_components * 2];
22837dd7cddfSDavid du Colombier        bool Interpolate;
22847dd7cddfSDavid du Colombier} gs_data_image_t;</pre>
22857dd7cddfSDavid du Colombier</blockquote>
22867dd7cddfSDavid du Colombier
22877dd7cddfSDavid du Colombier<p>
22887dd7cddfSDavid du ColombierImages that supply pixel (as opposed to mask) data are defined by:
22897dd7cddfSDavid du Colombier
22907dd7cddfSDavid du Colombier<blockquote>
22917dd7cddfSDavid du Colombier<pre>typedef enum {
22927dd7cddfSDavid du Colombier	/* Single plane, chunky pixels. */
22937dd7cddfSDavid du Colombier	gs_image_format_chunky = 0,
22947dd7cddfSDavid du Colombier	/* num_components planes, chunky components. */
22957dd7cddfSDavid du Colombier	gs_image_format_component_planar = 1,
22967dd7cddfSDavid du Colombier	/* BitsPerComponent * num_components planes, 1 bit per plane */
22977dd7cddfSDavid du Colombier	gs_image_format_bit_planar = 2
22987dd7cddfSDavid du Colombier} gs_image_format_t;
22997dd7cddfSDavid du Colombiertypedef struct {
23007dd7cddfSDavid du Colombier        &lt;&lt; gs_data_image_t &gt;&gt;
23017dd7cddfSDavid du Colombier        const gs_color_space *ColorSpace;
23027dd7cddfSDavid du Colombier        bool CombineWithColor;
23037dd7cddfSDavid du Colombier} gs_pixel_image_t;</pre>
23047dd7cddfSDavid du Colombier</blockquote>
23057dd7cddfSDavid du Colombier
23067dd7cddfSDavid du Colombier<p>
23077dd7cddfSDavid du ColombierOrdinary PostScript Level 1 or Level 2 (<b><tt>ImageType</tt></b> 1) images
23087dd7cddfSDavid du Colombierare defined by:
23097dd7cddfSDavid du Colombier
23107dd7cddfSDavid du Colombier<blockquote>
23117dd7cddfSDavid du Colombier<pre>typedef enum {
23127dd7cddfSDavid du Colombier	/* No alpha. */
23137dd7cddfSDavid du Colombier	gs_image_alpha_none = 0,
23147dd7cddfSDavid du Colombier	/* Alpha precedes color components. */
23157dd7cddfSDavid du Colombier	gs_image_alpha_first,
23167dd7cddfSDavid du Colombier	/* Alpha follows color components. */
23177dd7cddfSDavid du Colombier	gs_image_alpha_last
23187dd7cddfSDavid du Colombier} gs_image_alpha_t;
23197dd7cddfSDavid du Colombiertypedef struct {
23207dd7cddfSDavid du Colombier        &lt;&lt; gs_pixel_image_t &gt;&gt;
23217dd7cddfSDavid du Colombier        bool ImageMask;
23227dd7cddfSDavid du Colombier        bool adjust;
23237dd7cddfSDavid du Colombier	gs_image_alpha_t Alpha;
23247dd7cddfSDavid du Colombier} gs_image1_t;
23257dd7cddfSDavid du Colombiertypedef gs_image1_t gs_image_t;</pre>
23267dd7cddfSDavid du Colombier</blockquote>
23277dd7cddfSDavid du Colombier
23287dd7cddfSDavid du Colombier<p>
23297dd7cddfSDavid du ColombierOf course, standard PostScript images don't have an alpha component.  For
23303ff48bf5SDavid du Colombiermore details, consult the source code in <a
23313ff48bf5SDavid du Colombierhref="../src/gsiparam.h">gsiparam.h</a> and <b><tt>gsiparm*.h</tt></b>,
23323ff48bf5SDavid du Colombierwhich define parameters for an image.
23337dd7cddfSDavid du Colombier
23347dd7cddfSDavid du Colombier<p>
23357dd7cddfSDavid du ColombierThe <b><tt>begin[_typed_]image</tt></b> driver procedures create image
23367dd7cddfSDavid du Colombierenumeration structures.  The common part of these structures consists of:
23377dd7cddfSDavid du Colombier
23387dd7cddfSDavid du Colombier<blockquote>
23397dd7cddfSDavid du Colombier<pre>typedef struct gx_image_enum_common_s {
23407dd7cddfSDavid du Colombier        const gx_image_type_t *image_type;
23417dd7cddfSDavid du Colombier	const gx_image_enum_procs_t *procs;
23427dd7cddfSDavid du Colombier	gx_device *dev;
23437dd7cddfSDavid du Colombier	gs_id id;
23447dd7cddfSDavid du Colombier        int num_planes;
23457dd7cddfSDavid du Colombier        int plane_depths[gs_image_max_planes];  /* [num_planes] */
23467dd7cddfSDavid du Colombier	int plane_widths[gs_image_max_planes]	/* [num_planes] */
23477dd7cddfSDavid du Colombier} gx_image_enum_common_t;</pre>
23487dd7cddfSDavid du Colombier</blockquote>
23497dd7cddfSDavid du Colombier
23507dd7cddfSDavid du Colombier<p>
23517dd7cddfSDavid du Colombierwhere <b><tt>procs</tt></b> consists of:
23527dd7cddfSDavid du Colombier
23537dd7cddfSDavid du Colombier<blockquote>
23547dd7cddfSDavid du Colombier<pre>typedef struct gx_image_enum_procs_s {
23557dd7cddfSDavid du Colombier
23567dd7cddfSDavid du Colombier        /*
23577dd7cddfSDavid du Colombier         * Pass the next batch of data for processing.
23587dd7cddfSDavid du Colombier         */
23597dd7cddfSDavid du Colombier#define image_enum_proc_plane_data(proc)\
2360*593dc095SDavid du Colombier  int proc(gx_device *dev,\
23617dd7cddfSDavid du Colombier    gx_image_enum_common_t *info, const gx_image_plane_t *planes,\
2362*593dc095SDavid du Colombier    int height)
23637dd7cddfSDavid du Colombier
23647dd7cddfSDavid du Colombier        image_enum_proc_plane_data((*plane_data));
23657dd7cddfSDavid du Colombier
23667dd7cddfSDavid du Colombier        /*
23677dd7cddfSDavid du Colombier         * End processing an image, freeing the enumerator.
23687dd7cddfSDavid du Colombier         */
23697dd7cddfSDavid du Colombier#define image_enum_proc_end_image(proc)\
2370*593dc095SDavid du Colombier  int proc(gx_device *dev,\
2371*593dc095SDavid du Colombier    gx_image_enum_common_t *info, bool draw_last)
23727dd7cddfSDavid du Colombier
23737dd7cddfSDavid du Colombier        image_enum_proc_end_image((*end_image));
23747dd7cddfSDavid du Colombier
23757dd7cddfSDavid du Colombier	/*
23767dd7cddfSDavid du Colombier	 * Flush any intermediate buffers to the target device.
23777dd7cddfSDavid du Colombier	 * We need this for situations where two images interact
23787dd7cddfSDavid du Colombier	 * (currently, only the mask and the data of ImageType 3).
23797dd7cddfSDavid du Colombier	 * This procedure is optional (may be 0).
23807dd7cddfSDavid du Colombier	 */
23817dd7cddfSDavid du Colombier#define image_enum_proc_flush(proc)\
2382*593dc095SDavid du Colombier  int proc(gx_image_enum_common_t *info)
23837dd7cddfSDavid du Colombier
23847dd7cddfSDavid du Colombier	image_enum_proc_flush((*flush));
23857dd7cddfSDavid du Colombier
23867dd7cddfSDavid du Colombier} gx_image_enum_procs_t;</pre>
23877dd7cddfSDavid du Colombier</blockquote>
23887dd7cddfSDavid du Colombier
23897dd7cddfSDavid du Colombier<p> In other words, <b><tt>begin[_typed]_image</tt></b> sets up an
23907dd7cddfSDavid du Colombierenumeration structure that contains the procedures that will process the
23917dd7cddfSDavid du Colombierimage data, together with all variables needed to maintain the state of the
23927dd7cddfSDavid du Colombierprocess.  Since this is somewhat tricky to get right, if you plan to create
23937dd7cddfSDavid du Colombierone of your own you should probably read an existing implementation of
23943ff48bf5SDavid du Colombier<b><tt>begin[_typed]_image</tt></b>, such as the one in <a
23953ff48bf5SDavid du Colombierhref="../src/gdevbbox.c">gdevbbox.c</a> or <a
23963ff48bf5SDavid du Colombierhref="../src/gdevps.c">gdevps.c</a>.
23977dd7cddfSDavid du Colombier
23987dd7cddfSDavid du Colombier<p>
23997dd7cddfSDavid du ColombierThe data passed at each call of <b><tt>image_plane_data</tt></b> consists of
24007dd7cddfSDavid du Colombierone or more planes, as appropriate for the type of image.
24017dd7cddfSDavid du Colombier<b><tt>begin[_typed]_image</tt></b> must initialize the
24027dd7cddfSDavid du Colombier<b><tt>plane_depths</tt></b> array in the enumeration structure with the
24037dd7cddfSDavid du Colombierdepths (bits per element) of the planes.  The array of
24047dd7cddfSDavid du Colombier<b><tt>gx_image_plane_t</tt></b> structures passed to each call of
24057dd7cddfSDavid du Colombier<b><tt>image_plane_data</tt></b> then defines where the data are stored, as
24067dd7cddfSDavid du Colombierfollows:
24077dd7cddfSDavid du Colombier
24087dd7cddfSDavid du Colombier<blockquote>
24097dd7cddfSDavid du Colombier<pre>typedef struct gx_image_plane_s {
24107dd7cddfSDavid du Colombier  const byte *data;
24117dd7cddfSDavid du Colombier  int data_x;
24127dd7cddfSDavid du Colombier  uint raster;
24137dd7cddfSDavid du Colombier} gx_image_plane_t;</pre>
24147dd7cddfSDavid du Colombier</blockquote>
24157dd7cddfSDavid du Colombier
24167dd7cddfSDavid du Colombier<dl>
2417*593dc095SDavid du Colombier<dt><b><tt>int (*begin_image)(gx_device&nbsp;*dev,
24187dd7cddfSDavid du Colombierconst&nbsp;gs_imager_state&nbsp;*pis, const&nbsp;gs_image_t&nbsp;*pim,
24197dd7cddfSDavid du Colombiergs_image_format_t&nbsp;format, gs_int_rect&nbsp;*prect,
24207dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
24217dd7cddfSDavid du Colombierconst&nbsp;gx_clip_path&nbsp;*pcpath, gs_memory_t&nbsp;*memory,
2422*593dc095SDavid du Colombiergx_image_enum_common_t&nbsp;**pinfo)</tt></b> <b><em>[OPTIONAL]</em></b>
24237dd7cddfSDavid du Colombier<dd>Begin the transmission of an image.  Zero or more calls of
24247dd7cddfSDavid du Colombier<b><tt>image_plane_data</tt></b> will follow, and then a call of
24257dd7cddfSDavid du Colombier<b><tt>end_image</tt></b>.  The parameters of <b><tt>begin_image</tt></b>
24267dd7cddfSDavid du Colombierare as follows:
24277dd7cddfSDavid du Colombier
24287dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
24297dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pis</tt></b>
24307dd7cddfSDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;
24317dd7cddfSDavid du Colombier	<td>pointer to an imager state.  The only relevant elements of the
24327dd7cddfSDavid du Colombier	    imager state are the CTM (coordinate transformation matrix),
24337dd7cddfSDavid du Colombier	    the logical operation (<b><tt>RasterOp</tt></b> or
24347dd7cddfSDavid du Colombier	    transparency), and the color rendering information.
24357dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pim</tt></b>
24367dd7cddfSDavid du Colombier	<td>&nbsp;
24377dd7cddfSDavid du Colombier	<td>pointer to the <b><tt>gs_image_t</tt></b> structure that
24387dd7cddfSDavid du Colombier	    defines the image parameters
24397dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>format</tt></b>
24407dd7cddfSDavid du Colombier	<td>&nbsp;
24417dd7cddfSDavid du Colombier	<td>defines how pixels are represented for
24427dd7cddfSDavid du Colombier	    <b><tt>image_plane_data</tt></b>.  See the description of
24437dd7cddfSDavid du Colombier	    <b><tt>image_plane_data</tt></b> below
24447dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>prect</tt></b>
24457dd7cddfSDavid du Colombier	<td>&nbsp;
24467dd7cddfSDavid du Colombier	<td>if not <b><tt>NULL</tt></b>, defines a subrectangle of the
24477dd7cddfSDavid du Colombier	    image; only the data for this subrectangle will be passed to
24487dd7cddfSDavid du Colombier	    <b><tt>image_plane_data</tt></b>, and only this subrectangle should
24497dd7cddfSDavid du Colombier	    be drawn
24507dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pdcolor</tt></b>
24517dd7cddfSDavid du Colombier	<td>&nbsp;
24527dd7cddfSDavid du Colombier	<td>defines a drawing color, only needed for masks or if
24537dd7cddfSDavid du Colombier	    <b><tt>CombineWithColor</tt></b> is true
24547dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pcpath</tt></b>
24557dd7cddfSDavid du Colombier	<td>&nbsp;
24567dd7cddfSDavid du Colombier	<td>if not <b><tt>NULL</tt></b>, defines an optional clipping path
24577dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>memory</tt></b>
24587dd7cddfSDavid du Colombier	<td>&nbsp;
24597dd7cddfSDavid du Colombier	<td>defines the allocator to be used for allocating bookkeeping
24607dd7cddfSDavid du Colombier	    information
24617dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pinfo</tt></b>
24627dd7cddfSDavid du Colombier	<td>&nbsp;
24637dd7cddfSDavid du Colombier	<td>the implementation should return a pointer to its state
24647dd7cddfSDavid du Colombier	    structure here
24657dd7cddfSDavid du Colombier</table></blockquote>
24667dd7cddfSDavid du Colombier
24677dd7cddfSDavid du Colombier<p>
24687dd7cddfSDavid du Colombier<b><tt>begin_image</tt></b> is expected to allocate a structure for its
24697dd7cddfSDavid du Colombierbookkeeping needs, using the allocator defined by the memory parameter, and
24707dd7cddfSDavid du Colombierreturn it in <b><tt>*pinfo</tt></b>.  <b><tt>begin_image</tt></b> should not assume that
24717dd7cddfSDavid du Colombierthe structures in <b><tt>*pim</tt></b>, <b><tt>*prect</tt></b>, or
24727dd7cddfSDavid du Colombier<b><tt>*pdcolor</tt></b> will survive the call on
24737dd7cddfSDavid du Colombier<b><tt>begin_image</tt></b> (except for the color space in
24747dd7cddfSDavid du Colombier<b><tt>*pim-&gt;ColorSpace</tt></b>): it should copy any necessary parts of
24757dd7cddfSDavid du Colombierthem into its own bookkeeping structure.  It may, however, assume that
24767dd7cddfSDavid du Colombier<b><tt>*pis</tt></b>, <b><tt>*pcpath</tt></b>, and of course
24777dd7cddfSDavid du Colombier<b><tt>*memory</tt></b> will live at least until <b><tt>end_image</tt></b>
24787dd7cddfSDavid du Colombieris called.
24797dd7cddfSDavid du Colombier
24807dd7cddfSDavid du Colombier<p>
24817dd7cddfSDavid du Colombier<b><tt>begin_image</tt></b> returns 0 normally, or 1 if the image does not
24827dd7cddfSDavid du Colombierneed any data.  In the latter case, <b><tt>begin_image</tt></b> does not
24837dd7cddfSDavid du Colombierallocate an enumeration structure.
24847dd7cddfSDavid du Colombier</dl>
24857dd7cddfSDavid du Colombier
24867dd7cddfSDavid du Colombier<dl>
2487*593dc095SDavid du Colombier<dt><b><tt>int (*begin_typed_image)(gx_device&nbsp;*dev,
24887dd7cddfSDavid du Colombierconst&nbsp;gs_imager_state&nbsp;*pis, const&nbsp;gs_matrix&nbsp;*pmat,
24897dd7cddfSDavid du Colombierconst&nbsp;gs_image_common_t&nbsp;*pim, gs_int_rect&nbsp;*prect,
24907dd7cddfSDavid du Colombierconst&nbsp;gx_drawing_color&nbsp;*pdcolor,
24917dd7cddfSDavid du Colombierconst&nbsp;gx_clip_path&nbsp;*pcpath, gs_memory_t&nbsp;*memory,
2492*593dc095SDavid du Colombiergx_image_enum_common_t&nbsp;**pinfo)</tt></b> <b><em>[OPTIONAL]</em></b>
24937dd7cddfSDavid du Colombier<dd>This has the same function as <b><tt>begin_image</tt></b>, except
24947dd7cddfSDavid du Colombier<ul>
24957dd7cddfSDavid du Colombier<li>The image may be of any <b><tt>ImageType</tt></b>, not only
24967dd7cddfSDavid du Colombier<b><tt>image_type_simple</tt></b> (1);
24977dd7cddfSDavid du Colombier
24987dd7cddfSDavid du Colombier<li>The image format is included in the image structure, not supplied as a
24997dd7cddfSDavid du Colombierseparate argument;
25007dd7cddfSDavid du Colombier
25017dd7cddfSDavid du Colombier<li>The optional <b><tt>pmat</tt></b> argument provides a matrix that
25027dd7cddfSDavid du Colombiersubstitutes for the one in the imager state;
25037dd7cddfSDavid du Colombier
25047dd7cddfSDavid du Colombier<li>For mask images, if <b><tt>pmat</tt></b> is not <b><tt>NULL</tt></b>
25057dd7cddfSDavid du Colombierand the color is pure, <b><tt>pis</tt></b> may be <b><tt>NULL</tt></b>.
25067dd7cddfSDavid du Colombier</ul>
25077dd7cddfSDavid du Colombier</dl>
25087dd7cddfSDavid du Colombier
25097dd7cddfSDavid du Colombier<p>
25107dd7cddfSDavid du ColombierThe actual transmission of data uses the procedures in the enumeration
25117dd7cddfSDavid du Colombierstructure, not driver procedures, since the handling of the data usually
25127dd7cddfSDavid du Colombierdepends on the image type and parameters rather than the device.  These
25137dd7cddfSDavid du Colombierprocedures are specified as follows.
25147dd7cddfSDavid du Colombier
25157dd7cddfSDavid du Colombier<dl>
2516*593dc095SDavid du Colombier<dt><b><tt>int (*image_plane_data)(gx_device&nbsp;*dev,
25177dd7cddfSDavid du Colombiergx_image_enum_common_t&nbsp;*info,
2518*593dc095SDavid du Colombierconst&nbsp;gx_image_plane_t&nbsp;*planes, int&nbsp;height)</tt></b>
25197dd7cddfSDavid du Colombier<dd>This call provides more of the image source data: specifically,
25207dd7cddfSDavid du Colombier<b><tt>height</tt></b> rows, with <b><tt>Width</tt></b> pixels supplied for
25217dd7cddfSDavid du Colombiereach row.
25227dd7cddfSDavid du Colombier
25237dd7cddfSDavid du Colombier<p>
25247dd7cddfSDavid du ColombierThe data for each row are packed big-endian within each byte, as for
25257dd7cddfSDavid du Colombier<b><tt>copy_color</tt></b>.  The <b><tt>data_x</tt></b> (starting X position
25267dd7cddfSDavid du Colombierwithin the row) and <b><tt>raster</tt></b> (number of bytes per row) are
25277dd7cddfSDavid du Colombierspecified separately for each plane, and may include some padding at the
25287dd7cddfSDavid du Colombierbeginning or end of each row.  Note that for non-mask images, the input data
25297dd7cddfSDavid du Colombiermay be in any color space and may have any number of bits per component (1,
25307dd7cddfSDavid du Colombier2, 4, 8, 12); currently mask images always have 1 bit per component, but in
25317dd7cddfSDavid du Colombierthe future, they might allow multiple bits of alpha.  Note also that each
25327dd7cddfSDavid du Colombiercall of <b><tt>image_plane_data</tt></b> passes complete pixels: for example, for
25337dd7cddfSDavid du Colombiera chunky image with 24 bits per pixel, each call of
25347dd7cddfSDavid du Colombier<b><tt>image_plane_data</tt></b> passes 3N bytes of data (specifically,
25357dd7cddfSDavid du Colombier3&nbsp;&times;&nbsp;Width&nbsp;&times;&nbsp;height).
25367dd7cddfSDavid du Colombier
25377dd7cddfSDavid du Colombier<p>
25387dd7cddfSDavid du ColombierThe interpretation of planes depends on the <b><tt>format</tt></b> member of
25397dd7cddfSDavid du Colombierthe <b><tt>gs_image[_common]_t</tt></b> structure:
25407dd7cddfSDavid du Colombier
25417dd7cddfSDavid du Colombier<ul>
25427dd7cddfSDavid du Colombier<li>If the format is <b><tt>gs_image_format_chunky</tt></b>,
25437dd7cddfSDavid du Colombier<b><tt>planes[0].data</tt></b> points to data in "chunky" format, in which
25447dd7cddfSDavid du Colombierthe components follow each other (for instance, RGBRGBRGB....)
25457dd7cddfSDavid du Colombier
25467dd7cddfSDavid du Colombier<li>If the format is <b><tt>gs_image_format_component_planar</tt></b>,
25477dd7cddfSDavid du Colombier<b><tt>planes[0&nbsp;..&nbsp;N-1].data</tt></b> point to data for the
25487dd7cddfSDavid du Colombier<b><em>N</em></b> components (for example, <b><em>N</em></b>=3 for RGB
25497dd7cddfSDavid du Colombierdata); each plane contains samples for a single component, for instance,
25507dd7cddfSDavid du ColombierRR..., GG..., BB....  Note that the planes are divided by component, not by
25517dd7cddfSDavid du Colombierbit: for example, for 24-bit RGB data, <b><em>N</em></b>=3, with 8-bit
25527dd7cddfSDavid du Colombiervalues in each plane of data.
25537dd7cddfSDavid du Colombier
25547dd7cddfSDavid du Colombier<li>If the format is <b><tt>gs_image_format_bit_planar</tt></b>,
25557dd7cddfSDavid du Colombier<b><tt>planes[0&nbsp;..&nbsp;N*B-1].data</tt></b> point to data for the
25567dd7cddfSDavid du Colombier<b><em>N</em></b> components of <b><em>B</em></b> bits each (for example,
25577dd7cddfSDavid du Colombier<b><em>N</em></b>=3 and <b><em>B</em></b>=4 for RGB data with 4 bits per
25587dd7cddfSDavid du Colombiercomponent); each plane contains samples for a single bit, for instance, R0
25597dd7cddfSDavid du ColombierR1 R2 R3 G0 G1 G2 G3 B0 B1 B2 B3.  Note that the most significant bit of
25607dd7cddfSDavid du Colombiereach plane comes first.
25617dd7cddfSDavid du Colombier</ul>
25627dd7cddfSDavid du Colombier
25637dd7cddfSDavid du Colombier<p>
25647dd7cddfSDavid du ColombierIf, as a result of this call, <b><tt>image_plane_data</tt></b> has been called with all
25657dd7cddfSDavid du Colombierthe data for the (sub-)image, it returns 1; otherwise, it returns 0 or an
25667dd7cddfSDavid du Colombiererror code as usual.
25677dd7cddfSDavid du Colombier
25687dd7cddfSDavid du Colombier<p>
25697dd7cddfSDavid du Colombier<b><tt>image_plane_data</tt></b>, unlike most other procedures that take bitmaps as
25707dd7cddfSDavid du Colombierarguments, does not require the data to be aligned in any way.
25717dd7cddfSDavid du Colombier
25727dd7cddfSDavid du Colombier<p>
25737dd7cddfSDavid du ColombierNote that for some image types, different planes may have different
25747dd7cddfSDavid du Colombiernumbers of bits per pixel, as defined in the <b><tt>plane_depths</tt></b> array.
25757dd7cddfSDavid du Colombier</dl>
25767dd7cddfSDavid du Colombier
25777dd7cddfSDavid du Colombier<dl>
2578*593dc095SDavid du Colombier<dt><b><tt>int (*end_image)(gx_device&nbsp;*dev, void&nbsp;*info,
2579*593dc095SDavid du Colombierbool&nbsp;draw_last)</tt></b>
25807dd7cddfSDavid du Colombier<dd>Finish processing an image, either because all data have been supplied
25817dd7cddfSDavid du Colombieror because the caller has decided to abandon this image.
25827dd7cddfSDavid du Colombier<b><tt>end_image</tt></b> may be called at any time after
25837dd7cddfSDavid du Colombier<b><tt>begin_image</tt></b>.  It should free the info structure and any
25847dd7cddfSDavid du Colombiersubsidiary structures.  If <b><tt>draw_last</tt></b> is true, it should
25857dd7cddfSDavid du Colombierfinish drawing any buffered lines of the image.
25867dd7cddfSDavid du Colombier</dl>
25877dd7cddfSDavid du Colombier
25883ff48bf5SDavid du Colombier<h5><a name="Images_notes"></a>Notes</h5>
25897dd7cddfSDavid du Colombier
25907dd7cddfSDavid du Colombier<p>
25917dd7cddfSDavid du ColombierWhile there will almost never be more than one image enumeration in
25927dd7cddfSDavid du Colombierprogress -- that is, after a <b><tt>begin_image</tt></b>,
25937dd7cddfSDavid du Colombier<b><tt>end_image</tt></b> will almost always be called before the next
25947dd7cddfSDavid du Colombier<b><tt>begin_image</tt></b> -- driver code should not rely on this
25957dd7cddfSDavid du Colombierproperty; in particular, it should store all information regarding the
25967dd7cddfSDavid du Colombierimage in the info structure, not in the driver structure.
25977dd7cddfSDavid du Colombier
25987dd7cddfSDavid du Colombier<p>
25997dd7cddfSDavid du ColombierNote that if <b><tt>begin_[typed_]image</tt></b> saves its parameters in
26007dd7cddfSDavid du Colombierthe info structure, it can decide on each call whether to use its own
26017dd7cddfSDavid du Colombieralgorithms or to use the default implementation.  (It may need to call
26027dd7cddfSDavid du Colombier<b><tt>gx_default_begin</tt></b>/<b><tt>end_image</tt></b> partway
26037dd7cddfSDavid du Colombierthrough.)  [A later revision of this document may include an example here.]
26047dd7cddfSDavid du Colombier
26053ff48bf5SDavid du Colombier<h4><a name="Text"></a>Text</h4>
26067dd7cddfSDavid du Colombier
26077dd7cddfSDavid du Colombier<p>
26087dd7cddfSDavid du ColombierThe third high-level interface handles text.  As for images, the interface
26097dd7cddfSDavid du Colombieris based on creating an enumerator which then may execute the operation in
26107dd7cddfSDavid du Colombiermultiple steps.  As for the other high-level interfaces, the procedures are
26117dd7cddfSDavid du Colombieroptional.
26127dd7cddfSDavid du Colombier
26137dd7cddfSDavid du Colombier<dl>
2614*593dc095SDavid du Colombier<dt><b><tt>int (*text_begin)(gx_device&nbsp;*dev,
26157dd7cddfSDavid du Colombiergs_imager_state&nbsp;*pis, const&nbsp;gs_text_params_t&nbsp;*text,
26167dd7cddfSDavid du Colombiergs_font&nbsp;*font, gx_path&nbsp;*path,
26177dd7cddfSDavid du Colombierconst&nbsp;gx_device_color&nbsp;*pdcolor,
26187dd7cddfSDavid du Colombierconst&nbsp;gx_clip_path&nbsp;*pcpath, gs_memory_t&nbsp;*memory,
2619*593dc095SDavid du Colombiergs_text_enum_t&nbsp;**ppte)</tt></b> <b><em>[OPTIONAL]</em></b>
26207dd7cddfSDavid du Colombier
26213ff48bf5SDavid du Colombier<dd>
26227dd7cddfSDavid du ColombierBegin processing text, by creating a state structure and storing it in
26237dd7cddfSDavid du Colombier<b><tt>*ppte</tt></b>.  The parameters of <b><tt>text_begin</tt></b> are as
26247dd7cddfSDavid du Colombierfollows:
26257dd7cddfSDavid du Colombier</dl>
26267dd7cddfSDavid du Colombier
26277dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
26287dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>dev</tt></b>
26297dd7cddfSDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;
26307dd7cddfSDavid du Colombier	<td>The usual pointer to the device.
26317dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pis</tt></b>
26327dd7cddfSDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;
26337dd7cddfSDavid du Colombier	<td>A pointer to an imager state.  All elements may be relevant,
26347dd7cddfSDavid du Colombier	    depending on how the text is rendered.
26357dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>text</tt></b>
26367dd7cddfSDavid du Colombier	<td>&nbsp;
26377dd7cddfSDavid du Colombier	<td>A pointer to the structure that defines the text operation
26383ff48bf5SDavid du Colombier	    and parameters.  See <a href="../src/gstext.h">gstext.h</a> for details.
26397dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>font</tt></b>
26407dd7cddfSDavid du Colombier	<td>&nbsp;
26417dd7cddfSDavid du Colombier	<td>Defines the font for drawing.
26427dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>path</tt></b>
26437dd7cddfSDavid du Colombier	<td>&nbsp;
26447dd7cddfSDavid du Colombier	<td>Defines the path where the character outline will be appended
26457dd7cddfSDavid du Colombier	    (if the text operation includes <b><tt>TEXT_DO_...PATH</tt></b>),
26467dd7cddfSDavid du Colombier	    and whose current point indicates where drawing should occur
26477dd7cddfSDavid du Colombier	    and will be updated by the string width (unless the text
26487dd7cddfSDavid du Colombier	    operation includes <b><tt>TEXT_DO_NONE</tt></b>).
26497dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pdcolor</tt></b>
26507dd7cddfSDavid du Colombier	<td>&nbsp;
26517dd7cddfSDavid du Colombier	<td>Defines the drawing color for the text.  Only relevant if
26527dd7cddfSDavid du Colombier	    the text operation includes <b><tt>TEXT_DO_DRAW</tt></b>.
26537dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>pcpath</tt></b>
26547dd7cddfSDavid du Colombier	<td>&nbsp;
26557dd7cddfSDavid du Colombier	<td>If not <b><tt>NULL</tt></b>, defines an optional clipping path.
26567dd7cddfSDavid du Colombier	    Only relevant if the text operation includes
26577dd7cddfSDavid du Colombier	    <b><tt>TEXT_DO_DRAW</tt></b>.
26587dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>memory</tt></b>
26597dd7cddfSDavid du Colombier	<td>&nbsp;
26607dd7cddfSDavid du Colombier	<td>Defines the allocator to be used for allocating bookkeeping
26617dd7cddfSDavid du Colombier	    information.
26627dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>ppte</tt></b>
26637dd7cddfSDavid du Colombier	<td>&nbsp;
26647dd7cddfSDavid du Colombier	<td>The implementation should return a pointer to its state
26657dd7cddfSDavid du Colombier	    structure here.
26667dd7cddfSDavid du Colombier</table></blockquote>
26677dd7cddfSDavid du Colombier
26687dd7cddfSDavid du Colombier<p>
26697dd7cddfSDavid du Colombier<b><tt>text_begin</tt></b> must allocate a structure for its bookkeeping
26707dd7cddfSDavid du Colombierneeds, using the allocator defined by the <b><tt>memory</tt></b> parameter,
26717dd7cddfSDavid du Colombierand return it in <b><tt>*ppte</tt></b>.  <b><tt>text_begin</tt></b> may
26727dd7cddfSDavid du Colombierassume that the structures passed as parameters will survive until text
26737dd7cddfSDavid du Colombierprocessing is complete.
26747dd7cddfSDavid du Colombier
26757dd7cddfSDavid du Colombier<p>
26767dd7cddfSDavid du ColombierClients should not call the driver <b><tt>text_begin</tt></b> procedure
26773ff48bf5SDavid du Colombierdirectly.  Instead, they should call <b><tt>gx_device_text_begin</tt></b>,
26787dd7cddfSDavid du Colombierwhich takes the same parameters and also initializes certain common elements
26797dd7cddfSDavid du Colombierof the text enumeration structure, or <b><tt>gs_text_begin</tt></b>, which
26807dd7cddfSDavid du Colombiertakes many of the parameters from a graphics state structure.  For details,
26813ff48bf5SDavid du Colombiersee <a href="../src/gstext.h">gstext.h</a>.
26827dd7cddfSDavid du Colombier
26837dd7cddfSDavid du Colombier<p>
26847dd7cddfSDavid du ColombierThe actual processing of text uses the procedures in the enumeration
26857dd7cddfSDavid du Colombierstructure, not driver procedures, since the handling of the text may depend
26867dd7cddfSDavid du Colombieron the font and parameters rather than the device.  Text processing may also
26877dd7cddfSDavid du Colombierrequire the client to take action between characters, either because the
26887dd7cddfSDavid du Colombierclient requested it (<b><tt>TEXT_INTERVENE</tt></b> in the operation) or
26897dd7cddfSDavid du Colombierbecause rendering a character requires suspending text processing to call an
26907dd7cddfSDavid du Colombierexternal package such as the PostScript interpreter.  (It is a deliberate
26917dd7cddfSDavid du Colombierdesign decision to handle this by returning to the client, rather than
26927dd7cddfSDavid du Colombiercalling out of the text renderer, in order to avoid potentially unknown
26937dd7cddfSDavid du Colombierstack requirements.)  Specifically, the client must call the following
26947dd7cddfSDavid du Colombierprocedures, which in turn call the procedures in the text enumerator.
26957dd7cddfSDavid du Colombier
26967dd7cddfSDavid du Colombier<dl>
2697*593dc095SDavid du Colombier<dt><b><tt>int gs_text_process(gs_text_enum_t&nbsp;*pte)</tt></b>
26987dd7cddfSDavid du Colombier<dd>Continue processing text.  This procedure may return 0 or a negative
26997dd7cddfSDavid du Colombiererror code as usual, or one of the following values (see
27003ff48bf5SDavid du Colombier<a href="../src/gstext.h">gstext.h</a> for details).
27017dd7cddfSDavid du Colombier
27027dd7cddfSDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
27037dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>TEXT_PROCESS_RENDER</tt></b>
27047dd7cddfSDavid du Colombier	<td>The client must cause the current character to be rendered.
27057dd7cddfSDavid du Colombier	    This currently only is used for PostScript Type 0-4 fonts
27067dd7cddfSDavid du Colombier	    and their CID-keyed relatives.
27077dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>TEXT_PROCESS_INTERVENE</tt></b>
27087dd7cddfSDavid du Colombier	<td>The client has asked to intervene between characters.
27097dd7cddfSDavid du Colombier	    This is used for <b><tt>cshow</tt></b> and <b><tt>kshow</tt></b>.
27107dd7cddfSDavid du Colombier</table></blockquote>
27117dd7cddfSDavid du Colombier</dl>
27127dd7cddfSDavid du Colombier
27137dd7cddfSDavid du Colombier<dl>
2714*593dc095SDavid du Colombier<dt><b><tt>int gs_text_release(gs_text_enum_t&nbsp;*pte,
2715*593dc095SDavid du Colombierclient_name_t&nbsp;cname)</tt></b> <dd>Finish processing text and release
27167dd7cddfSDavid du Colombierall associated structures.  Clients must call this procedure after
27177dd7cddfSDavid du Colombier<b><tt>gs_text_process</tt></b> returns 0 or an error, and may call it at
27187dd7cddfSDavid du Colombierany time.
27197dd7cddfSDavid du Colombier</dl>
27207dd7cddfSDavid du Colombier
27217dd7cddfSDavid du Colombier<p>
27227dd7cddfSDavid du ColombierThere are numerous other procedures that clients may call during text
27233ff48bf5SDavid du Colombierprocessing.  See <a href="../src/gstext.h">gstext.h</a> for details.
27247dd7cddfSDavid du Colombier
27253ff48bf5SDavid du Colombier<h5><a name="Text_notes"></a>Notes</h5>
27263ff48bf5SDavid du Colombier
27273ff48bf5SDavid du Colombier<p>
27283ff48bf5SDavid du ColombierNote that unlike many other optional procedures, the default implementation
27293ff48bf5SDavid du Colombierof <b><tt>text_begin</tt></b> cannot simply return: like the default
27303ff48bf5SDavid du Colombierimplementation of <b><tt>begin[_typed]_image</tt></b>, it must create and
27313ff48bf5SDavid du Colombierreturn an enumerator.  Furthermore, the implementation of the
27323ff48bf5SDavid du Colombier<b><tt>process</tt></b> procedure (in the enumerator structure, called by
27333ff48bf5SDavid du Colombier<b><tt>gs_text_process</tt></b>) cannot simply return without doing
27343ff48bf5SDavid du Colombieranything, even if it doesn't want to draw anything on the output.  See the
27353ff48bf5SDavid du Colombiercomments in <a href="../src/gxtext.h">gxtext.h</a> for details.
27363ff48bf5SDavid du Colombier
2737*593dc095SDavid du Colombier<h4><a name="Unicode"></a>Unicode support for high level devices</h4>
2738*593dc095SDavid du Colombier
2739*593dc095SDavid du Colombier<p>
2740*593dc095SDavid du Colombier<p>Implementing a new high level device, one may need to translate <b><tt>Postscript</tt></b>
2741*593dc095SDavid du Colombiercharacter codes into <b><tt>Unicode</tt></b>. This can be done pretty simply.
2742*593dc095SDavid du Colombier
2743*593dc095SDavid du Colombier<p>For translating a <b><tt>Postscript</tt></b> text you need to inplement the device
2744*593dc095SDavid du Colombiervirtual function <b><tt>text_begin</tt></b>. It should create a new instance of
2745*593dc095SDavid du Colombier<b><tt>gs_text_enum_t</tt></b> in the heap (let its pointer be <b><tt>pte</tt></b>),
2746*593dc095SDavid du Colombierand assign a special function to <b><tt>gs_text_enum_t::procs.process</tt></b>.
2747*593dc095SDavid du ColombierThe function will receive <b><tt>pte</tt></b>. It should take the top level font from
2748*593dc095SDavid du Colombier<b><tt>pte->orig_font</tt></b>,
2749*593dc095SDavid du Colombierand iterate with <b><tt>font->procs.next_char_glyph(pte, ..., &glyph)</tt></b>.
2750*593dc095SDavid du ColombierThe last argument receives a <b><tt>gs_glyph</tt></b> value, which encodes a
2751*593dc095SDavid du Colombier<b><tt>Postscript</tt></b> character name or CID (and also stores it into
2752*593dc095SDavid du Colombier<b><tt>pte->returned.current_glyph</tt></b>).
2753*593dc095SDavid du ColombierThen obtain the current subfont with <b><tt>gs_text_current_font(pte)</tt></b>
2754*593dc095SDavid du Colombier(it can differ from the font)
2755*593dc095SDavid du Colombierand call <b><tt>subfont->procs.decode_glyph(subfont, glyph)</tt></b>.
2756*593dc095SDavid du ColombierThe return value will be an <b><tt>Unicode</tt></b> code, or <b><tt>GS_NO_CHAR</tt></b>
2757*593dc095SDavid du Colombierif the glyph can't be translated to Unicode.
2758*593dc095SDavid du Colombier
27593ff48bf5SDavid du Colombier<h3><a name="Reading_bits_back"></a>Reading bits back</h3>
27607dd7cddfSDavid du Colombier
27617dd7cddfSDavid du Colombier<dl>
2762*593dc095SDavid du Colombier<dt><b><tt>int (*get_bits_rectangle)(gx_device&nbsp;*dev,
27637dd7cddfSDavid du Colombierconst&nbsp;gs_int_rect&nbsp;*prect, gs_get_bits_params_t&nbsp;*params,
2764*593dc095SDavid du Colombiergs_int_rect&nbsp;**unread)</tt></b> <b><em>[OPTIONAL]</em></b>
27657dd7cddfSDavid du Colombier
27663ff48bf5SDavid du Colombier<dd>
27677dd7cddfSDavid du ColombierRead a rectangle of bits back from the device.  The <b><tt>params</tt></b>
27687dd7cddfSDavid du Colombierstructure consists of:
27697dd7cddfSDavid du Colombier
27703ff48bf5SDavid du Colombier<table cellpadding=0 cellspacing=0>
27717dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>options</tt></b>
27727dd7cddfSDavid du Colombier	<td>&nbsp;
27737dd7cddfSDavid du Colombier	<td>the allowable formats for returning the data
27747dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>data[32]</tt></b>
27757dd7cddfSDavid du Colombier	<td>&nbsp;
27767dd7cddfSDavid du Colombier	<td>pointers to the returned data
27777dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>x_offset</tt></b>
27787dd7cddfSDavid du Colombier	<td>&nbsp;
27797dd7cddfSDavid du Colombier	<td>the X offset of the first returned pixel in data
27807dd7cddfSDavid du Colombier<tr valign=top>	<td><b><tt>raster</tt></b>
27817dd7cddfSDavid du Colombier	<td>&nbsp;
27827dd7cddfSDavid du Colombier	<td>the distance between scan lines in the returned data
27833ff48bf5SDavid du Colombier</table>
27847dd7cddfSDavid du Colombier
27857dd7cddfSDavid du Colombier<p>
27867dd7cddfSDavid du Colombier<b><tt>options</tt></b> is a bit mask specifying what formats the client is
27877dd7cddfSDavid du Colombierwilling to accept.  (If the client has more flexibility, the implementation
27887dd7cddfSDavid du Colombiermay be able to return the data more efficiently, by avoiding representation
27897dd7cddfSDavid du Colombierconversions.)  The options are divided into groups.
27907dd7cddfSDavid du Colombier
27917dd7cddfSDavid du Colombier<blockquote><dl>
27927dd7cddfSDavid du Colombier<dt><b><em>alignment</em></b>
27937dd7cddfSDavid du Colombier<dd>Specifies whether the returned data must be aligned in the normal
27947dd7cddfSDavid du Colombiermanner for bitmaps, or whether unaligned data are acceptable.
27957dd7cddfSDavid du Colombier
27967dd7cddfSDavid du Colombier<dt><b><em>pointer or copy</em></b>
27977dd7cddfSDavid du Colombier<dd>Specifies whether the data may be copied into storage provided by the
27987dd7cddfSDavid du Colombierclient and/or returned as pointers to existing storage. (Note that if
27997dd7cddfSDavid du Colombiercopying is not allowed, it is much more likely that the implementation will
28007dd7cddfSDavid du Colombierreturn an error, since this requires that the client accept the data in the
28017dd7cddfSDavid du Colombierimplementation's internal format.)
28027dd7cddfSDavid du Colombier
28037dd7cddfSDavid du Colombier<dt><b><em>X offset</em></b>
28047dd7cddfSDavid du Colombier<dd>Specifies whether the returned data must have a specific X offset
28057dd7cddfSDavid du Colombier(usually zero, but possibly other values to avoid skew at some later stage
28067dd7cddfSDavid du Colombierof processing) or whether it may have any X offset (which may avoid skew in
28077dd7cddfSDavid du Colombierthe <b><tt>get_bits_rectangle</tt></b> operation itself).
28087dd7cddfSDavid du Colombier
28097dd7cddfSDavid du Colombier<dt><b><em>raster</em></b>
28107dd7cddfSDavid du Colombier<dd>Specifies whether the raster (distance between returned scan lines)
28117dd7cddfSDavid du Colombiermust have its standard value, must have some other specific value, or may
28127dd7cddfSDavid du Colombierhave any value.  The standard value for the raster is the device width
28137dd7cddfSDavid du Colombierpadded out to the alignment modulus when using pointers, or the minimum
28147dd7cddfSDavid du Colombierraster to accommodate the X offset + width when copying (padded out to the
28157dd7cddfSDavid du Colombieralignment modulus if standard alignment is required).
28167dd7cddfSDavid du Colombier
28177dd7cddfSDavid du Colombier<dt><b><em>format</em></b>
28187dd7cddfSDavid du Colombier<dd>Specifies whether the data are returned in chunky (all components of a
28197dd7cddfSDavid du Colombiersingle pixel together), component-planar (each component has its own scan
28207dd7cddfSDavid du Colombierlines), or bit-planar (each bit has its own scan lines) format.
28217dd7cddfSDavid du Colombier
28227dd7cddfSDavid du Colombier<dt><b><em>color space</em></b>
28237dd7cddfSDavid du Colombier<dd>Specifies whether the data are returned as native device pixels, or in
28247dd7cddfSDavid du Colombiera standard color space.  Currently the only supported standard space is
28257dd7cddfSDavid du ColombierRGB.
28267dd7cddfSDavid du Colombier
28277dd7cddfSDavid du Colombier<dt><b><em>standard component depth</em></b>
28287dd7cddfSDavid du Colombier<dd>Specifies the number of bits per component if the data are returned in
28297dd7cddfSDavid du Colombierthe standard color space.  (Native device pixels use
28307dd7cddfSDavid du Colombier<b><tt>dev</tt></b>-&gt;<b><tt>color_info.depth</tt></b> bits per pixel.)
28317dd7cddfSDavid du Colombier
28327dd7cddfSDavid du Colombier<dt><b><em>alpha</em></b>
28337dd7cddfSDavid du Colombier<dd>Specifies whether alpha channel information should be returned as the
28347dd7cddfSDavid du Colombierfirst component, the last component, or not at all.  Note that for devices
28357dd7cddfSDavid du Colombierthat have no alpha capability, the returned alpha values will be all 1s.
28367dd7cddfSDavid du Colombier</dl></blockquote>
28377dd7cddfSDavid du Colombier
28387dd7cddfSDavid du Colombier<p>
28397dd7cddfSDavid du ColombierThe client may set more than one option in each of the above groups; the
28407dd7cddfSDavid du Colombierimplementation will choose one of the selected options in each group to
28417dd7cddfSDavid du Colombierdetermine the actual form of the returned data, and will update
28427dd7cddfSDavid du Colombier<b><tt>params[].options</tt></b> to indicate the form.  The returned
28437dd7cddfSDavid du Colombier<b><tt>params[].options</tt></b> will normally have only one option set per
28447dd7cddfSDavid du Colombiergroup.
28457dd7cddfSDavid du Colombier
28467dd7cddfSDavid du Colombier<p>
28473ff48bf5SDavid du ColombierFor further details on <b><tt>params</tt></b>, see <a
28483ff48bf5SDavid du Colombierhref="../src/gxgetbit.h">gxgetbit.h</a>.  For further details on
28493ff48bf5SDavid du Colombier<b><tt>options</tt></b>, see <a href="../src/gxbitfmt.h">gxbitfmt.h</a>.
28507dd7cddfSDavid du Colombier
28517dd7cddfSDavid du Colombier<p>
28527dd7cddfSDavid du ColombierDefine w = <b><tt>prect</tt></b>-&gt;q.x - <b><tt>prect</tt></b>-&gt;p.x, h
28537dd7cddfSDavid du Colombier= <b><tt>prect</tt></b>-&gt;q.y - <b><tt>prect</tt></b>-&gt;p.y.  If the
28547dd7cddfSDavid du Colombierbits cannot be read back (for example, from a printer), return
28557dd7cddfSDavid du Colombier<b><tt>gs_error_unknownerror</tt></b>; if raster bytes is not enough space
28567dd7cddfSDavid du Colombierto hold <b><tt>offset_x</tt></b> + w pixels, or if the source rectangle
28577dd7cddfSDavid du Colombiergoes outside the device dimensions (p.x &lt; 0 || p.y &lt; 0 || q.x &gt;
28587dd7cddfSDavid du Colombier<b><tt>dev</tt></b>-&gt;width || q.y &gt; <b><tt>dev</tt></b>-&gt;height),
28597dd7cddfSDavid du Colombierreturn <b><tt>gs_error_rangecheck</tt></b>; if any regions could not be
28607dd7cddfSDavid du Colombierread, return <b><tt>gs_error_ioerror</tt></b> if unpainted is
28617dd7cddfSDavid du Colombier<b><tt>NULL</tt></b>, otherwise the number of rectangles (see below);
28627dd7cddfSDavid du Colombierotherwise return 0.
28637dd7cddfSDavid du Colombier
28647dd7cddfSDavid du Colombier<p>
28657dd7cddfSDavid du ColombierThe caller supplies a buffer of <b><tt>raster</tt></b>&nbsp;&times;&nbsp;h
28667dd7cddfSDavid du Colombierbytes starting at <b><tt>data[0]</tt></b> for the returned data in chunky
28677dd7cddfSDavid du Colombierformat, or <b><em>N</em></b> buffers of
28687dd7cddfSDavid du Colombier<b><tt>raster</tt></b>&nbsp;&times;&nbsp;h bytes starting at
28697dd7cddfSDavid du Colombier<b><tt>data[0]</tt></b> through
28707dd7cddfSDavid du Colombier<b><tt>data[</tt></b><b><em>N-1</em></b><b><tt>]</tt></b> in planar format
28717dd7cddfSDavid du Colombierwhere <b><em>N</em></b> is the number of components or bits.  The contents
28727dd7cddfSDavid du Colombierof the bits beyond the last valid bit in each scan line (as defined by w)
28737dd7cddfSDavid du Colombierare unpredictable.  data need not be aligned in any way.  If
28747dd7cddfSDavid du Colombier<b><tt>x_offset</tt></b> is non-zero, the bits before the first valid bit
28757dd7cddfSDavid du Colombierin each scan line are undefined.  If the implementation returns pointers to
28767dd7cddfSDavid du Colombierthe data, it stores them into <b><tt>data[0]</tt></b> or
28777dd7cddfSDavid du Colombier<b><tt>data[</tt></b><b><em>0..N-1</em></b><b><tt>]</tt></b>.
28787dd7cddfSDavid du Colombier
28797dd7cddfSDavid du Colombier<p>
28807dd7cddfSDavid du ColombierIf not all the source data are available (for example, because the source
28817dd7cddfSDavid du Colombierwas a partially obscured window and backing store was not available or not
28827dd7cddfSDavid du Colombierused), or if the rectangle does not fall completely within the device's
28837dd7cddfSDavid du Colombiercoordinate system, any unread bits are undefined, and the value returned
28847dd7cddfSDavid du Colombierdepends on whether unread is <b><tt>NULL</tt></b>.  If unread is
28857dd7cddfSDavid du Colombier<b><tt>NULL</tt></b>, return <b><tt>gs_error_ioerror</tt></b>; in this case,
28867dd7cddfSDavid du Colombiersome bits may or may not have been read.  If unread is not
28877dd7cddfSDavid du Colombier<b><tt>NULL</tt></b>, allocate (using <b><tt>dev</tt></b>-&gt;memory) and
28887dd7cddfSDavid du Colombierfill in a list of rectangles that could not be read, store the pointer to
28897dd7cddfSDavid du Colombierthe list in <b><tt>*unread</tt></b>, and return the number of rectangles; in
28907dd7cddfSDavid du Colombierthis case, all bits not listed in the rectangle list have been read back
28917dd7cddfSDavid du Colombierproperly.  The list is not sorted in any particular order, but the
28927dd7cddfSDavid du Colombierrectangles do not overlap.  Note that the rectangle list may cover a
28937dd7cddfSDavid du Colombiersuperset of the region actually obscured: for example, a lazy implementation
28947dd7cddfSDavid du Colombiercould return a single rectangle that was the bounding box of the region.
28957dd7cddfSDavid du Colombier</dl>
28967dd7cddfSDavid du Colombier
28977dd7cddfSDavid du Colombier<dl>
2898*593dc095SDavid du Colombier<dt><b><tt>int (*get_bits)(gx_device&nbsp;*dev, int&nbsp;y,
2899*593dc095SDavid du Colombierbyte&nbsp;*data, byte&nbsp;**actual_data)</tt></b>
29007dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
29017dd7cddfSDavid du Colombier<dd>Read scan line <b><tt>y</tt></b> of bits back from the device into the
29027dd7cddfSDavid du Colombierarea starting at data.  This call is functionally equivalent to
29037dd7cddfSDavid du Colombier
29047dd7cddfSDavid du Colombier<blockquote>
29057dd7cddfSDavid du Colombier<pre>(*get_bits_rectangle)
29067dd7cddfSDavid du Colombier  (dev, {0, y, dev-&gt;width, y+1},
29077dd7cddfSDavid du Colombier   {(GB_ALIGN_ANY | (GB_RETURN_COPY | GB_RETURN_POINTER) | GB_OFFSET_0 |
29087dd7cddfSDavid du Colombier     GB_RASTER_STANDARD | GB_FORMAT_CHUNKY | GB_COLORS_NATIVE |
29097dd7cddfSDavid du Colombier     GB_ALPHA_NONE),
29107dd7cddfSDavid du Colombier    {data}})</pre></blockquote>
29117dd7cddfSDavid du Colombier
29127dd7cddfSDavid du Colombier<p>
29137dd7cddfSDavid du Colombierwith the returned value of
29147dd7cddfSDavid du Colombier<b><tt>params</tt></b>-&gt;<b><tt>data[0]</tt></b> stored in
29157dd7cddfSDavid du Colombier<b><tt>*actual_data</tt></b>, and will in fact be implemented this way if
29167dd7cddfSDavid du Colombierthe device defines a <b><tt>get_bits_rectangle</tt></b> procedure and does
29177dd7cddfSDavid du Colombiernot define one for <b><tt>get_bits</tt></b>.  (If
29187dd7cddfSDavid du Colombier<b><tt>actual_data</tt></b> is <b><tt>NULL</tt></b>,
29197dd7cddfSDavid du Colombier<b><tt>GB_RETURN_POINTER</tt></b> is omitted from the options.)
29207dd7cddfSDavid du Colombier</dl>
29217dd7cddfSDavid du Colombier
29223ff48bf5SDavid du Colombier<h3><a name="Parameters"></a>Parameters</h3>
29237dd7cddfSDavid du Colombier
29247dd7cddfSDavid du Colombier<p>
29257dd7cddfSDavid du ColombierDevices may have an open-ended set of parameters, which are simply pairs
29267dd7cddfSDavid du Colombierconsisting of a name and a value.  The value may be of various types:
29277dd7cddfSDavid du Colombierinteger (int or long), boolean, float, string, name, <b><tt>NULL</tt></b>,
29287dd7cddfSDavid du Colombierarray of integer, array of float, or arrays or dictionaries of mixed types.
29297dd7cddfSDavid du ColombierFor example, the <b><tt>Name</tt></b> of a device is a string; the
29307dd7cddfSDavid du Colombier<b><tt>Margins</tt></b> of a device is an array of two floats.  See
29313ff48bf5SDavid du Colombier<a href="../src/gsparam.h">gsparam.h</a> for more details.
29327dd7cddfSDavid du Colombier
29337dd7cddfSDavid du Colombier<p>
29347dd7cddfSDavid du ColombierIf a device has parameters other than the ones applicable to all devices
29357dd7cddfSDavid du Colombier(or, in the case of printer devices, all printer devices), it must provide
29367dd7cddfSDavid du Colombier<b><tt>get_params</tt></b> and <b><tt>put_params</tt></b> procedures.  If
29377dd7cddfSDavid du Colombieryour device has parameters beyond those of a straightforward display or
29387dd7cddfSDavid du Colombierprinter, we strongly advise using the <b><tt>_get_params</tt></b> and
29397dd7cddfSDavid du Colombier<b><tt>_put_params</tt></b> procedures in an existing device (for example,
29403ff48bf5SDavid du Colombier<a href="../src/gdevcdj.c">gdevcdj.c</a> or <a
29413ff48bf5SDavid du Colombierhref="../src/gdevbit.c">gdevbit.c</a>) as a model for your own code.
29427dd7cddfSDavid du Colombier
29437dd7cddfSDavid du Colombier<dl>
2944*593dc095SDavid du Colombier<dt><b><tt>int (*get_params)(gx_device&nbsp;*dev,
2945*593dc095SDavid du Colombiergs_param_list&nbsp;*plist)</tt></b> <b><em>[OPTIONAL]</em></b>
29467dd7cddfSDavid du Colombier<dd>Read the parameters of the device into the parameter list at
29477dd7cddfSDavid du Colombier<b><tt>plist</tt></b>, using the <b><tt>param_write_*</tt></b>
29483ff48bf5SDavid du Colombiermacros or procedures defined in <a href="../src/gsparam.h">gsparam.h</a>.
29497dd7cddfSDavid du Colombier</dl>
29507dd7cddfSDavid du Colombier
29517dd7cddfSDavid du Colombier<dl>
2952*593dc095SDavid du Colombier<dt><b><tt>int (*get_hardware_params)(gx_device&nbsp;*dev,
2953*593dc095SDavid du Colombiergs_param_list&nbsp;*plist)</tt></b> <b><em>[OPTIONAL]</em></b>
29547dd7cddfSDavid du Colombier<dd>Read the hardware-related parameters of the device into the parameter
29557dd7cddfSDavid du Colombierlist at plist.  These are any parameters whose values are under control of
29567dd7cddfSDavid du Colombierexternal forces rather than the program -- for example, front panel
29577dd7cddfSDavid du Colombierswitches, paper jam or tray empty sensors, etc.  If a parameter involves
29587dd7cddfSDavid du Colombiersignificant delay or hardware action, the driver should only determine the
29597dd7cddfSDavid du Colombiervalue of the parameter if it is "requested" by the
29607dd7cddfSDavid du Colombier<b><tt>gs_param_list</tt></b> [<b><tt>param_requested</tt></b>(plist,
29617dd7cddfSDavid du Colombier<b><tt>key_name</tt></b>)].  This function may cause the asynchronous
29627dd7cddfSDavid du Colombierrendering pipeline (if enabled) to be drained, so it should be used
29637dd7cddfSDavid du Colombiersparingly.
29647dd7cddfSDavid du Colombier</dl>
29657dd7cddfSDavid du Colombier
29667dd7cddfSDavid du Colombier<dl>
2967*593dc095SDavid du Colombier<dt><b><tt>int (*put_params)(gx_device&nbsp;*dev,
2968*593dc095SDavid du Colombiergs_param_list&nbsp;*plist)</tt></b> <b><em>[OPTIONAL]</em></b>
29697dd7cddfSDavid du Colombier<dd>Set the parameters of the device from the parameter list at
29707dd7cddfSDavid du Colombier<b><tt>plist</tt></b>, using the <b><tt>param_read_</tt></b>*
29713ff48bf5SDavid du Colombiermacros/procedures defined in <a href="../src/gsparam.h">gsparam.h</a>.  All
29727dd7cddfSDavid du Colombier<b><tt>put_params</tt></b> procedures must use a "two-phase commit"
29733ff48bf5SDavid du Colombieralgorithm; see <a href="../src/gsparam.h">gsparam.h</a> for details.
29747dd7cddfSDavid du Colombier</dl>
29757dd7cddfSDavid du Colombier
29763ff48bf5SDavid du Colombier<h4><a name="Default_CRD_parameters"></a>Default color rendering
29773ff48bf5SDavid du Colombierdictionary (CRD) parameters</h4>
29787dd7cddfSDavid du Colombier
29797dd7cddfSDavid du Colombier<p>
29807dd7cddfSDavid du ColombierDrivers that want to provide one or more default CIE color rendering
29817dd7cddfSDavid du Colombierdictionaries (CRDs) can do so through <b><tt>get_params</tt></b>.  To do
29827dd7cddfSDavid du Colombierthis, they create the CRD in the usual way (normally using the
29837dd7cddfSDavid du Colombier<b><tt>gs_cie_render1_build</tt></b> and <b><tt>_initialize</tt></b>
29843ff48bf5SDavid du Colombierprocedures defined in <a href="../src/gscrd.h">gscrd.h</a>), and then write
29853ff48bf5SDavid du Colombierit as a parameter using <b><tt>param_write_cie_render1</tt></b> defined in
29863ff48bf5SDavid du Colombier<a href="../src/gscrdp.h">gscrdp.h</a>.  However, the TransformPQR procedure
29873ff48bf5SDavid du Colombierrequires special handling.  If the CRD uses a TransformPQR procedure
29883ff48bf5SDavid du Colombierdifferent from the default (identity), the driver must do the following:
29897dd7cddfSDavid du Colombier
29907dd7cddfSDavid du Colombier<ul>
29917dd7cddfSDavid du Colombier<li>The TransformPQR element of the CRD must include a
29927dd7cddfSDavid du Colombier<b><tt>proc_name</tt></b>, and optionally <b><tt>proc_data</tt></b>.  The
29937dd7cddfSDavid du Colombier<b><tt>proc_name</tt></b> is an arbitrary name chosen by the driver to
29947dd7cddfSDavid du Colombierdesignate the particular TransformPQR function.  It must not be the same as
29957dd7cddfSDavid du Colombierany device parameter name; we strongly suggest it include the device name,
29967dd7cddfSDavid du Colombierfor instance, "<b><tt>bitTPQRDefault</tt></b>".
29977dd7cddfSDavid du Colombier
29987dd7cddfSDavid du Colombier<li>For each such named TransformPQR procedure, the driver's
29997dd7cddfSDavid du Colombier<b><tt>get_param</tt></b> procedure must provide a parameter of the same
30007dd7cddfSDavid du Colombiername.  The parameter value must be a string whose bytes are the actual
30017dd7cddfSDavid du Colombierprocedure address.
30027dd7cddfSDavid du Colombier</ul>
30037dd7cddfSDavid du Colombier
30047dd7cddfSDavid du Colombier<p>
30057dd7cddfSDavid du ColombierFor a complete example, see the <b><tt>bit_get_params</tt></b> procedure in
30063ff48bf5SDavid du Colombier<a href="../src/gdevbit.c">gdevbit.c</a>.  Note that it is essential that
30073ff48bf5SDavid du Colombierthe driver return the CRD or the procedure address only if specifically
30083ff48bf5SDavid du Colombierrequested (<b><tt>param_requested(...)</tt></b> &gt; 0); otherwise, errors
30093ff48bf5SDavid du Colombierwill occur.
30107dd7cddfSDavid du Colombier
30113ff48bf5SDavid du Colombier<h3><a name="External_fonts"></a>External fonts</h3>
30127dd7cddfSDavid du Colombier
30137dd7cddfSDavid du Colombier<p>
30147dd7cddfSDavid du ColombierDrivers may include the ability to display text.  More precisely, they may
30157dd7cddfSDavid du Colombiersupply a set of procedures that in turn implement some font and text
30167dd7cddfSDavid du Colombierhandling capabilities, described in <a href="Xfonts.htm">a separate
30177dd7cddfSDavid du Colombierdocument</a>.  The link between the two is the driver procedure that
30187dd7cddfSDavid du Colombiersupplies the font and text procedures:
30197dd7cddfSDavid du Colombier
30207dd7cddfSDavid du Colombier<dl>
3021*593dc095SDavid du Colombier<dt><b><tt>xfont_procs&nbsp;*(*get_xfont_procs)(gx_device&nbsp;*dev)</tt></b> <b><em>[OPTIONAL]</em></b>
30227dd7cddfSDavid du Colombier<dd>Return a structure of procedures for handling external fonts and text
30237dd7cddfSDavid du Colombierdisplay.  A <b><tt>NULL</tt></b> value means that this driver doesn't
30247dd7cddfSDavid du Colombierprovide this capability.
30257dd7cddfSDavid du Colombier</dl>
30267dd7cddfSDavid du Colombier
30277dd7cddfSDavid du Colombier<p>
30287dd7cddfSDavid du ColombierFor technical reasons, a second procedure is also needed:
30297dd7cddfSDavid du Colombier
30307dd7cddfSDavid du Colombier<dl>
3031*593dc095SDavid du Colombier<dt><b><tt>gx_device&nbsp;*(*get_xfont_device)(gx_device&nbsp;*dev)</tt></b> <b><em>[OPTIONAL]</em></b>
30327dd7cddfSDavid du Colombier<dd>Return the device that implements <b><tt>get_xfont_procs</tt></b> in a
30337dd7cddfSDavid du Colombiernon-default way for this device, if any.  Except for certain special
30347dd7cddfSDavid du Colombierinternal devices, this is always the device argument.
30357dd7cddfSDavid du Colombier</dl>
30367dd7cddfSDavid du Colombier
30373ff48bf5SDavid du Colombier<h3><a name="Page_devices"></a>Page devices</h3>
30387dd7cddfSDavid du Colombier
30397dd7cddfSDavid du Colombier<dl>
3040*593dc095SDavid du Colombier<dt><b><tt>gx_device&nbsp;*(*get_page_device)(gx_device&nbsp;*dev)</tt></b>
30417dd7cddfSDavid du Colombier<b><em>[OPTIONAL]</em></b>
30427dd7cddfSDavid du Colombier<dd>According to the Adobe specifications, some devices are "page devices"
30437dd7cddfSDavid du Colombierand some are not.  This procedure returns <b><tt>NULL</tt></b> if the
30447dd7cddfSDavid du Colombierdevice is not a page device, or the device itself if it is a page device.
30457dd7cddfSDavid du ColombierIn the case of forwarding devices, <b><tt>get_page_device</tt></b> returns
30467dd7cddfSDavid du Colombierthe underlying page device (or <b><tt>NULL</tt></b> if the underlying
30477dd7cddfSDavid du Colombierdevice is not a page device).
30487dd7cddfSDavid du Colombier</dl>
30497dd7cddfSDavid du Colombier
30503ff48bf5SDavid du Colombier<h3><a name="Miscellaneous"></a>Miscellaneous</h3>
30517dd7cddfSDavid du Colombier
30527dd7cddfSDavid du Colombier<dl>
3053*593dc095SDavid du Colombier<dt><b><tt>int (*get_band)(gx_device&nbsp;*dev, int&nbsp;y,
3054*593dc095SDavid du Colombierint&nbsp;*band_start)</tt></b> <b><em>[OPTIONAL]</em></b>
30557dd7cddfSDavid du Colombier<dd>If the device is a band device, this procedure stores in
30567dd7cddfSDavid du Colombier<b><tt>*band_start</tt></b> the scan line (device Y coordinate) of the band
30577dd7cddfSDavid du Colombierthat includes the given Y coordinate, and returns the number of scan lines
30587dd7cddfSDavid du Colombierin the band.  If the device is not a band device, this procedure returns 0.
30597dd7cddfSDavid du ColombierThe latter is the default implementation.
30607dd7cddfSDavid du Colombier</dl>
30617dd7cddfSDavid du Colombier
30627dd7cddfSDavid du Colombier<dl>
3063*593dc095SDavid du Colombier<dt><b><tt>void (*get_clipping_box)(gx_device&nbsp;*dev,
30647dd7cddfSDavid du Colombiergs_fixed_rect&nbsp;*pbox))</tt></b> <b><em>[OPTIONAL]</em></b>
30657dd7cddfSDavid du Colombier<dd>Stores in <b><tt>*pbox</tt></b> a rectangle that defines the device's
30667dd7cddfSDavid du Colombierclipping region.  For all but a few specialized devices, this is
30677dd7cddfSDavid du Colombier<em>((0,0),(width,height))</em>.
30687dd7cddfSDavid du Colombier</dl>
30697dd7cddfSDavid du Colombier
30707dd7cddfSDavid du Colombier<!-- [2.0 end contents] ==================================================== -->
30717dd7cddfSDavid du Colombier
30727dd7cddfSDavid du Colombier<!-- [3.0 begin visible trailer] =========================================== -->
30737dd7cddfSDavid du Colombier<hr>
30747dd7cddfSDavid du Colombier
30753ff48bf5SDavid du Colombier<p>
30763ff48bf5SDavid du Colombier<small>Copyright &copy; 1996, 2000 Aladdin Enterprises.
30773ff48bf5SDavid du ColombierAll rights reserved.</small>
30787dd7cddfSDavid du Colombier
30797dd7cddfSDavid du Colombier<p>
3080*593dc095SDavid du ColombierThis software is provided AS-IS with no warranty, either express or
3081*593dc095SDavid du Colombierimplied.
3082*593dc095SDavid du Colombier
3083*593dc095SDavid du ColombierThis software is distributed under license and may not be copied,
3084*593dc095SDavid du Colombiermodified or distributed except as expressly authorized under the terms
3085*593dc095SDavid du Colombierof the license contained in the file LICENSE in this distribution.
3086*593dc095SDavid du Colombier
3087*593dc095SDavid du ColombierFor more information about licensing, please refer to
3088*593dc095SDavid du Colombierhttp://www.ghostscript.com/licensing/. For information on
3089*593dc095SDavid du Colombiercommercial licensing, go to http://www.artifex.com/licensing/ or
3090*593dc095SDavid du Colombiercontact Artifex Software, Inc., 101 Lucas Valley Road #110,
3091*593dc095SDavid du ColombierSan Rafael, CA  94903, U.S.A., +1(415)492-9861.
30927dd7cddfSDavid du Colombier
30933ff48bf5SDavid du Colombier<p>
3094*593dc095SDavid du Colombier<small>Ghostscript version 8.53, 20 October 2005
30957dd7cddfSDavid du Colombier
30967dd7cddfSDavid du Colombier<!-- [3.0 end visible trailer] ============================================= -->
30977dd7cddfSDavid du Colombier
3098*593dc095SDavid du Colombier</small></body>
30997dd7cddfSDavid du Colombier</html>
3100