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 *</tt></b> as 2497dd7cddfSDavid du Colombiertheir first argument, and must cast it to 2507dd7cddfSDavid du Colombier<b><tt>smurf_device *</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> 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> 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> 2827dd7cddfSDavid du Colombier <td>Color information 2837dd7cddfSDavid du Colombier<tr valign=top> <td><b><tt>int width;</tt></b> 2847dd7cddfSDavid du Colombier <td> 2857dd7cddfSDavid du Colombier <td>Width in pixels 2867dd7cddfSDavid du Colombier<tr valign=top> <td><b><tt>int height;</tt></b> 2877dd7cddfSDavid du Colombier <td> 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 (>= 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 (>= 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> × <b><tt>dither_rgb</tt></b> × <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> ) 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 < 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 <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 * 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 * get_color_mapping_procs(const 1228*593dc095SDavid du Colombiergx_device * 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 * dev, 1246*593dc095SDavid du Colombiergx_color_value * 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 *, gx_color_index color, 1261*593dc095SDavid du Colombiergx_color_value * 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 *, 12717dd7cddfSDavid du Colombiergx_color_value red, gx_color_value green, 1272*593dc095SDavid du Colombiergx_color_value blue, gx_color_value 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, r, g, b, gx_max_color_value)</tt></b> 12857dd7cddfSDavid du Colombierreturns the same value as 1286*593dc095SDavid du Colombier<b><tt>encode_color(dev, 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 *, 1291*593dc095SDavid du Colombiergx_color_index color, gx_color_value 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 enum { go_text, 13117dd7cddfSDavid du Colombiergo_graphics } graphic_object_type; int 1312*593dc095SDavid du Colombier(*get_alpha_bits)(gx_device *dev, 1313*593dc095SDavid du Colombiergraphic_object_type 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 *, 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 *, int x, 13407dd7cddfSDavid du Colombierint y, int width, int height, 1341*593dc095SDavid du Colombiergx_color_index color)</tt></b> 13427dd7cddfSDavid du Colombier<dd>Fill a rectangle with a color. The set of pixels filled is {(px,py) | 13437dd7cddfSDavid du Colombierx <= px < x + width and y <= py < 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> <= 0 or 13487dd7cddfSDavid du Colombierheight <= 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 *, 13677dd7cddfSDavid du Colombierconst unsigned char *data, int data_x, int raster, 13687dd7cddfSDavid du Colombiergx_bitmap_id id, int x, int y, int width, 13697dd7cddfSDavid du Colombierint height, gx_color_index color0, 1370*593dc095SDavid du Colombiergx_color_index 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> = <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 *, 13957dd7cddfSDavid du Colombierconst gx_tile_bitmap *tile, int x, int y, 13967dd7cddfSDavid du Colombierint width, int height, gx_color_index color0, 1397*593dc095SDavid du Colombiergx_color_index color1, int phase_x, int 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 != 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 *, 14107dd7cddfSDavid du Colombierconst gx_strip_bitmap *tile, int x, int y, 14117dd7cddfSDavid du Colombierint width, int height, gx_color_index color0, 1412*593dc095SDavid du Colombiergx_color_index color1, int phase_x, int 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->width</tt></b><em>)</em> and 14237dd7cddfSDavid du Colombier<em>[0..</em><b><tt>tile->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 *, 14537dd7cddfSDavid du Colombierconst unsigned char *data, int data_x, int raster, 14547dd7cddfSDavid du Colombiergx_bitmap_id id, int x, int y, int width, 1455*593dc095SDavid du Colombierint 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 *dev, 14897dd7cddfSDavid du Colombierconst unsigned char *data, int data_x, int raster, 14907dd7cddfSDavid du Colombiergx_bitmap_id id, int x, int y, int width, 1491*593dc095SDavid du Colombierint height, gx_color_index color, int 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 *dev, 15127dd7cddfSDavid du Colombiergx_device_t **pcdev, const gs_composite_t *pcte, 1513*593dc095SDavid du Colombierconst gs_imager_state *pis, gs_memory_t *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 *dev, 15727dd7cddfSDavid du Colombierconst byte *sdata, int sourcex, uint sraster, 15737dd7cddfSDavid du Colombiergx_bitmap_id id, const gx_color_index *scolors, 15747dd7cddfSDavid du Colombierconst gx_tile_bitmap *texture, 15757dd7cddfSDavid du Colombierconst gx_color_index *tcolors, int x, int y, 15767dd7cddfSDavid du Colombierint width, int height, int phase_x, int phase_y, 1577*593dc095SDavid du Colombierint 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 != 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 *dev, 15897dd7cddfSDavid du Colombierconst byte *sdata, int sourcex, uint sraster, 15907dd7cddfSDavid du Colombiergx_bitmap_id id, const gx_color_index *scolors, 15917dd7cddfSDavid du Colombierconst gx_strip_bitmap *texture, 15927dd7cddfSDavid du Colombierconst gx_color_index *tcolors, int x, int y, 15937dd7cddfSDavid du Colombierint width, int height, int phase_x, int phase_y, 1594*593dc095SDavid du Colombierint 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 = 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> 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> 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> 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> 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> 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> 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> 17387dd7cddfSDavid du Colombier <td> 17397dd7cddfSDavid du Colombier<tr valign=top> <td>7-0 17407dd7cddfSDavid du Colombier <td> 17417dd7cddfSDavid du Colombier <td>raster op 17427dd7cddfSDavid du Colombier<tr valign=top> <td>8 17437dd7cddfSDavid du Colombier <td> 17447dd7cddfSDavid du Colombier <td>0 if source opaque, 1 if source transparent 17457dd7cddfSDavid du Colombier<tr valign=top> <td>9 17467dd7cddfSDavid du Colombier <td> 17477dd7cddfSDavid du Colombier <td>0 if texture opaque, 1 if texture transparent 17487dd7cddfSDavid du Colombier<tr valign=top> <td>?-10 17497dd7cddfSDavid du Colombier <td> 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×2×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> 17627dd7cddfSDavid du Colombier <th>Texture 17637dd7cddfSDavid du Colombier <td> 17647dd7cddfSDavid du Colombier <th>Source 17657dd7cddfSDavid du Colombier <td> 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> 17707dd7cddfSDavid du Colombier <td align=center>1 17717dd7cddfSDavid du Colombier <td> 17727dd7cddfSDavid du Colombier <td align=center>1 17737dd7cddfSDavid du Colombier <td> 17747dd7cddfSDavid du Colombier <td align=center>1 17757dd7cddfSDavid du Colombier<tr valign=top> <td align=center>6 17767dd7cddfSDavid du Colombier <td> 17777dd7cddfSDavid du Colombier <td align=center>1 17787dd7cddfSDavid du Colombier <td> 17797dd7cddfSDavid du Colombier <td align=center>1 17807dd7cddfSDavid du Colombier <td> 17817dd7cddfSDavid du Colombier <td align=center>0 17827dd7cddfSDavid du Colombier<tr valign=top> <td align=center>5 17837dd7cddfSDavid du Colombier <td> 17847dd7cddfSDavid du Colombier <td align=center>1 17857dd7cddfSDavid du Colombier <td> 17867dd7cddfSDavid du Colombier <td align=center>0 17877dd7cddfSDavid du Colombier <td> 17887dd7cddfSDavid du Colombier <td align=center>1 17897dd7cddfSDavid du Colombier<tr valign=top> <td align=center>4 17907dd7cddfSDavid du Colombier <td> 17917dd7cddfSDavid du Colombier <td align=center>1 17927dd7cddfSDavid du Colombier <td> 17937dd7cddfSDavid du Colombier <td align=center>0 17947dd7cddfSDavid du Colombier <td> 17957dd7cddfSDavid du Colombier <td align=center>0 17967dd7cddfSDavid du Colombier<tr valign=top> <td align=center>3 17977dd7cddfSDavid du Colombier <td> 17987dd7cddfSDavid du Colombier <td align=center>0 17997dd7cddfSDavid du Colombier <td> 18007dd7cddfSDavid du Colombier <td align=center>1 18017dd7cddfSDavid du Colombier <td> 18027dd7cddfSDavid du Colombier <td align=center>1 18037dd7cddfSDavid du Colombier<tr valign=top> <td align=center>2 18047dd7cddfSDavid du Colombier <td> 18057dd7cddfSDavid du Colombier <td align=center>0 18067dd7cddfSDavid du Colombier <td> 18077dd7cddfSDavid du Colombier <td align=center>1 18087dd7cddfSDavid du Colombier <td> 18097dd7cddfSDavid du Colombier <td align=center>0 18107dd7cddfSDavid du Colombier<tr valign=top> <td align=center>1 18117dd7cddfSDavid du Colombier <td> 18127dd7cddfSDavid du Colombier <td align=center>0 18137dd7cddfSDavid du Colombier <td> 18147dd7cddfSDavid du Colombier <td align=center>0 18157dd7cddfSDavid du Colombier <td> 18167dd7cddfSDavid du Colombier <td align=center>1 18177dd7cddfSDavid du Colombier<tr valign=top> <td align=center>0 18187dd7cddfSDavid du Colombier <td> 18197dd7cddfSDavid du Colombier <td align=center>0 18207dd7cddfSDavid du Colombier <td> 18217dd7cddfSDavid du Colombier <td align=center>0 18227dd7cddfSDavid du Colombier <td> 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) ==> 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) ==> 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) ==> 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) ==> 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) ==> [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) ==> 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 *dev, const 1929*593dc095SDavid du Colombiergs_fixed_edge *left, const gs_fixed_edge *right, 19303ff48bf5SDavid du Colombierfixed ybot, fixed ytop, bool swap_axes, 19317dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 1932*593dc095SDavid du Colombiergs_logical_operation_t 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 *dev, 19477dd7cddfSDavid du Colombierfixed px, fixed py, fixed ax, fixed ay, fixed bx, 19487dd7cddfSDavid du Colombierfixed by, const gx_drawing_color *pdcolor, 1949*593dc095SDavid du Colombiergs_logical_operation_t 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 *dev, fixed px, 19597dd7cddfSDavid du Colombierfixed py, fixed ax, fixed ay, fixed bx, fixed by, 19607dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 1961*593dc095SDavid du Colombiergs_logical_operation_t 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 *dev, 19687dd7cddfSDavid du Colombierfixed fx0, fixed fy0, fixed fx1, fixed fy1, 19697dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 1970*593dc095SDavid du Colombiergs_logical_operation_t 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 *dev, int x0, int y0, 1977*593dc095SDavid du Colombierint x1, int y1, gx_color_index 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> 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> 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> 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> 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> 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> 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> 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> 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> 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 *dev, 22063ff48bf5SDavid du Colombierconst gs_imager_state *pis, gx_path *ppath, 22077dd7cddfSDavid du Colombierconst gx_fill_params *params, 22087dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 2209*593dc095SDavid du Colombierconst gx_clip_path *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 *dev, 22273ff48bf5SDavid du Colombierconst gs_imager_state *pis, gx_path *ppath, 22287dd7cddfSDavid du Colombierconst gx_stroke_params *params, 22297dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 2230*593dc095SDavid du Colombierconst gx_clip_path *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 *dev, 22387dd7cddfSDavid du Colombierconst byte *data, int data_x, int raster, 22397dd7cddfSDavid du Colombiergx_bitmap_id id, int x, int y, int width, 22407dd7cddfSDavid du Colombierint height, const gx_drawing_color *pdcolor, int depth, 2241*593dc095SDavid du Colombierint command, const gx_clip_path *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> > 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 << gs_image_common_t >> 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 << gs_data_image_t >> 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 << gs_pixel_image_t >> 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 *dev, 24187dd7cddfSDavid du Colombierconst gs_imager_state *pis, const gs_image_t *pim, 24197dd7cddfSDavid du Colombiergs_image_format_t format, gs_int_rect *prect, 24207dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 24217dd7cddfSDavid du Colombierconst gx_clip_path *pcpath, gs_memory_t *memory, 2422*593dc095SDavid du Colombiergx_image_enum_common_t **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> 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> 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> 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> 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> 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> 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> 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> 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->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 *dev, 24887dd7cddfSDavid du Colombierconst gs_imager_state *pis, const gs_matrix *pmat, 24897dd7cddfSDavid du Colombierconst gs_image_common_t *pim, gs_int_rect *prect, 24907dd7cddfSDavid du Colombierconst gx_drawing_color *pdcolor, 24917dd7cddfSDavid du Colombierconst gx_clip_path *pcpath, gs_memory_t *memory, 2492*593dc095SDavid du Colombiergx_image_enum_common_t **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 *dev, 25177dd7cddfSDavid du Colombiergx_image_enum_common_t *info, 2518*593dc095SDavid du Colombierconst gx_image_plane_t *planes, int 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 × Width × 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 .. 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 .. 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 *dev, void *info, 2579*593dc095SDavid du Colombierbool 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 *dev, 26157dd7cddfSDavid du Colombiergs_imager_state *pis, const gs_text_params_t *text, 26167dd7cddfSDavid du Colombiergs_font *font, gx_path *path, 26177dd7cddfSDavid du Colombierconst gx_device_color *pdcolor, 26187dd7cddfSDavid du Colombierconst gx_clip_path *pcpath, gs_memory_t *memory, 2619*593dc095SDavid du Colombiergs_text_enum_t **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> 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> 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> 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> 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> 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> 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> 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> 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> 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 *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 *pte, 2715*593dc095SDavid du Colombierclient_name_t 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 *dev, 27637dd7cddfSDavid du Colombierconst gs_int_rect *prect, gs_get_bits_params_t *params, 2764*593dc095SDavid du Colombiergs_int_rect **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> 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> 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> 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> 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>-><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>->q.x - <b><tt>prect</tt></b>->p.x, h 28537dd7cddfSDavid du Colombier= <b><tt>prect</tt></b>->q.y - <b><tt>prect</tt></b>->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 < 0 || p.y < 0 || q.x > 28587dd7cddfSDavid du Colombier<b><tt>dev</tt></b>->width || q.y > <b><tt>dev</tt></b>->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> × 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> × 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>->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 *dev, int y, 2899*593dc095SDavid du Colombierbyte *data, byte **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->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>-><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 *dev, 2945*593dc095SDavid du Colombiergs_param_list *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 *dev, 2953*593dc095SDavid du Colombiergs_param_list *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 *dev, 2968*593dc095SDavid du Colombiergs_param_list *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> > 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 *(*get_xfont_procs)(gx_device *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 *(*get_xfont_device)(gx_device *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 *(*get_page_device)(gx_device *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 *dev, int y, 3054*593dc095SDavid du Colombierint *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 *dev, 30647dd7cddfSDavid du Colombiergs_fixed_rect *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 © 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