⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivers.htm

📁 GhostScript的源代码
💻 HTM
📖 第 1 页 / 共 5 页
字号:
long as instances are created only by calling the
<b><tt>gs_copydevice</tt></b> procedure defined in
<b><tt>gsdevice.h</tt></b>.  If you have a need to define devices that are
not registered in this way, you must fill in the stype member in any
dynamically allocated instances with a pointer to the same structure
descriptor used to allocate the instance.  For more information about
structure descriptors, see <b><tt>gsmemory.h</tt></b> and
<b><tt>gsstruct.h</tt></b>.

<hr>

<h1><a name="Printer_drivers"></a>Printer drivers</h1>

<p>
Printer drivers (which include drivers that write some kind of raster file)
are especially simple to implement.  Of the driver procedures defined in
the next section, they only need implement two:
<b><tt>map_rgb_color</tt></b> (or <b><tt>map_cmyk_color</tt></b>) and
<b><tt>map_color_rgb</tt></b>.  In addition, they must implement a
<b><tt>print_page</tt></b> or <b><tt>print_page_copies</tt></b> procedure.
There are macros in <b><tt>gdevprn.h</tt></b> that generate the device
structure for such devices, of which the simplest is
<b><tt>prn_device</tt></b>; for an example, see <b><tt>gdevbj10.c</tt></b>.
If you are writing a printer driver, we suggest you start by reading
<b><tt>gdevprn.h</tt></b> and the <a href="#Color_mapping">subsection on
"Color mapping"</a> below; you may be able to ignore all the rest of the
driver procedures.

<p>
The <b><tt>print_page</tt></b> procedures are defined as follows:

<blockquote>
<pre>int (*print_page)(P2(gx_device_printer *, FILE *))
int (*print_page_copies)(P3(gx_device_printer *, FILE *, int))</pre>
</blockquote>

<p>
This procedure must read out the rendered image from the device and write
whatever is appropriate to the file.  To read back one or more scan lines
of the image, the <b><tt>print_page</tt></b> procedure must call one of the
following procedures:

<blockquote>
<pre>int gdev_prn_copy_scan_lines(P4(gx_device_printer *pdev, int y, byte *str,
    uint size)</pre>
</blockquote>

<p>
For this procedure, <b><tt>str</tt></b> is where the data should be copied to, and <b><tt>size</tt></b> is
the size of the buffer starting at <b><tt>str</tt></b>.  This procedure returns the number
of scan lines copied, or &lt;0 for an error.  <b><tt>str</tt></b> need not be aligned.

<blockquote>
<pre>int gdev_prn_get_bits(gx_device_printer *pdev, int y, byte *str,
  byte **actual_data)</pre>
</blockquote>

<p>
This procedure reads out exactly one scan line.  If the scan line is
available in the correct format already, <b><tt>*actual_data</tt></b> is
set to point to it; otherwise, the scan line is copied to the buffer
starting at <b><tt>str</tt></b>, and <b><tt>*actual_data</tt></b> is set to
<b><tt>str</tt></b>.  This saves a copying step most of the time.
<b><tt>str</tt></b> need not be aligned; however, if
<b><tt>*actual_data</tt></b> is set to point to an existing scan line, it
will be aligned.  (See the description of the <b><tt>get_bits</tt></b>
procedure below for more details.)

<p>
In either case, each row of the image is stored in the form described in
the comment under <b><tt>gx_tile_bitmap</tt></b> above; each pixel takes
the number of bits specified as <b><tt>color_info.depth</tt></b> in the
device structure, and holds values returned by the device's
<b><tt>map_</tt></b>{<b><tt>rgb</tt></b>,<b><tt>cmyk</tt></b>}<b><tt>_color</tt></b>
procedure.

<p>
The <b><tt>print_page</tt></b> procedure can determine the number of bytes
required to hold a scan line by calling:

<blockquote>
<pre>uint gdev_prn_raster(P1(gx_device_printer *))</pre>
</blockquote>

<p>
For a very simple concrete example, we suggest reading the code in
<b><tt>bit_print_page</tt></b> in <b><tt>gdevbit.c</tt></b>.

<p>
If the device provides <b><tt>print_page</tt></b>, Ghostscript will call
<b><tt>print_page</tt></b> the requisite number of times to print the
desired number of copies; if the device provides
<b><tt>print_page_copies</tt></b>, Ghostscript will call
<b><tt>print_page_copies</tt></b> once per page, passing it the desired
number of copies.

<hr>

<h1><a name="Driver_procedures"></a>Driver procedures</h1>

<p>
Most of the procedures that a driver may implement are optional.  If a
device doesn't supply an optional procedure <b><tt>WXYZ</tt></b>, the entry
in the procedure structure may be either <b><tt>gx_default_WXYZ</tt></b>,
for instance <b><tt>gx_default_tile_rectangle</tt></b>, or
<b><tt>NULL</tt></b> or 0.  (The device procedure must also call the
<b><tt>gx_default_</tt></b> procedure if it doesn't implement the function
for particular values of the arguments.)  Since C compilers supply 0 as the
value for omitted structure elements, this convention means that statically
initialized procedure structures continue to work even if new (optional)
members are added.

<h2><a name="Life_cycle"></a>Life cycle</h2>

<p>
A device instance begins life in a closed state.  In this state, no output
operations will occur.  Only the following procedures may be called:

<blockquote><b><tt>
open_device<br>
get_initial_matrix<br>
get_params<br>
put_params<br>
get_hardware_params
</tt></b></blockquote>

<p>
When <b><tt>setdevice</tt></b> installs a device instance in the graphics
state, it checks whether the instance is closed or open.  If the instance
is closed, <b><tt>setdevice</tt></b> calls the open routine, and then sets
the state to open.  There is currently no user-accessible operation to
close a device instance.  Device instances are only closed when they are
about to be freed, which occurs in three situations:

<ul>
<li>when a 'restore' occurs, if the instance was created since the
corresponding 'save';
<li>by the garbage collector, if the instance is no longer accessible; or
<li>when Ghostscript exits (terminates).
</ul>

<h2><a name="Open_close"></a>Open, close, sync</h2>

<dl>
<dt><b><tt>int (*open_device)(P1(gx_device *))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Open the device: do any initialization associated with making the
device instance valid.  This must be done before any output to the device.
The default implementation does nothing.
</dl>

<dl>
<dt><b><tt>void (*get_initial_matrix)(P2(gx_device *, gs_matrix *))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Construct the initial transformation matrix mapping user coordinates
(nominally 1/72 inch per unit) to device coordinates.  The default
procedure computes this from width, height, and
[<b><tt>xy</tt></b>]<b><tt>_pixels_per_inch</tt></b> on the assumption that
the origin is in the upper left corner, that is
<blockquote>
<b><tt>xx</tt></b> = <b><tt>x_pixels_per_inch</tt></b>/72, <b><tt>xy</tt></b> = 0,<br>
<b><tt>yx = 0, yy = -y_pixels_per_inch</tt></b>/72,<br>
<b><tt>tx = 0, ty = height</tt></b>.
</blockquote>
</dl>

<dl>
<dt><b><tt>int (*sync_output)(P1(gx_device *))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Synchronize the device.  If any output to the device has been
buffered, send or write it now.  Note that this may be called several times
in the process of constructing a page, so printer drivers should <b>not</b>
implement this by printing the page.  The default implementation does
nothing.
</dl>

<dl>
<dt><b><tt>int (*output_page)(P3(gx_device *, int num_copies, int flush))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Output a fully composed page to the device.  The
<b><tt>num_copies</tt></b> argument is the number of copies that should be
produced for a hardcopy device.  (This may be ignored if the driver has
some other way to specify the number of copies.)  The <b><tt>flush</tt></b>
argument is true for <b><tt>showpage</tt></b>, false for
<b><tt>copypage</tt></b>.  The default definition just calls
<b><tt>sync_output</tt></b>.  Printer drivers should implement this by
printing and ejecting the page.
</dl>

<dl>
<dt><b><tt>int (*close_device)(P1(gx_device *))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Close the device: release any associated resources.  After this, output
to the device is no longer allowed.  The default implementation does
nothing.
</dl>

<h2><a name="Color_mapping"></a>Color and alpha mapping</h2>

<p>
A given driver normally implements either <b><tt>map_rgb_color</tt></b> or
<b><tt>map_cmyk_color</tt></b>, but not both.  Black-and-white drivers need
implement neither.  Note that the <b><tt>map_xxx_color</tt></b> procedures
must not return <b><tt>gx_no_color_index</tt></b> (all 1s).

<dl>
<dt><b><tt>gx_color_index (*map_rgb_color)(P4(gx_device&nbsp;*,
gx_color_value&nbsp;red, gx_color_value&nbsp;green,
gx_color_value&nbsp;blue))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Map a RGB color to a device color.  The range of legal values of the
RGB arguments is 0 to <b><tt>gx_max_color_value</tt></b>.  The default
algorithm uses the <b><tt>map_cmyk_color</tt></b> procedure if the driver
supplies one, otherwise returns 1 if any of the values exceeds
<b><tt>gx_max_color_value</tt></b>&nbsp;/&nbsp;2, 0 otherwise.

<p>
Ghostscript assumes that for devices that have color capability (that is,
<b><tt>color_info.num_components</tt></b> &gt; 1),
<b><tt>map_rgb_color</tt></b> returns a color index for a gray level (as
opposed to a non-gray color) iff red = green = blue.
</dl>

<dl>
<dt><b><tt>gx_color_index (*map_cmyk_color)(P5(gx_device&nbsp;*,
gx_color_value&nbsp;cyan, gx_color_value&nbsp;magenta,
gx_color_value&nbsp;yellow, gx_color_value&nbsp;black))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Map a CMYK color to a device color.  The range of legal values of the
CMYK arguments is 0 to <b><tt>gx_max_color_value</tt></b>.  The default
algorithm calls the <b><tt>map_rgb_color</tt></b> procedure, with suitably
transformed arguments.

<p>
Ghostscript assumes that for devices that have color capability (that is,
<b><tt>color_info.num_components</tt></b> &gt; 1),
<b><tt>map_cmyk_color</tt></b> returns a color index for a gray level (as
opposed to a non-gray color) iff cyan = magenta = yellow.
</dl>

<dl>
<dt><b><tt>int (*map_color_rgb)(P3(gx_device&nbsp;*,
gx_color_index&nbsp;color, gx_color_value&nbsp;rgb[3]))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Map a device color code to RGB values.  The default algorithm returns
(0 if <b><tt>color</tt></b>==0 else <b><tt>gx_max_color_value</tt></b>) for
all three components.
</dl>

<dl>
<dt><b><tt>gx_color_index (*map_rgb_alpha_color)(P5(gx_device&nbsp;*,
gx_color_value&nbsp;red, gx_color_value&nbsp;green,
gx_color_value&nbsp;blue, gx_color_value&nbsp;alpha))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Map a RGB color and an opacity value to a device color.  The range of
legal values of the RGB and alpha arguments is 0 to
<b><tt>gx_max_color_value</tt></b>; <b><tt>alpha</tt></b> = 0 means
transparent, <b><tt>alpha</tt></b> = <b><tt>gx_max_color_value</tt></b>
means fully opaque.  The default is to use the
<b><tt>map_rgb_color</tt></b> procedure and ignore alpha.

<p>
Note that if a driver implements <b><tt>map_rgb_alpha_color</tt></b>, it
must also implement <b><tt>map_rgb_color</tt></b>, and must implement them
in such a way that
<b><tt>map_rgb_alpha_color(dev,&nbsp;r,&nbsp;g,&nbsp;b,&nbsp;gx_max_color_value)</tt></b>
returns the same value as
<b><tt>map_rgb_color(dev,&nbsp;r,&nbsp;g,&nbsp;b)</tt></b>.
</dl>

<dl>
<dt><b><tt>int (*map_color_rgb_alpha)(P3(gx_device&nbsp;*,
gx_color_index&nbsp;color, gx_color_value&nbsp;rgba[4]))</tt></b>
<b><em>[OPTIONAL]</em></b>
<dd>Map a device color code to RGB and alpha values.  The default
implementation calls <b><tt>map_color_rgb</tt></b> and fills in
<b><tt>gx_max_color_value</tt></b> for alpha.

<p>
Note that if a driver implements <b><tt>map_color_rgb_alpha</tt></b>, it
must also implement <b><tt>map_color_rgb</tt></b>, and must implement them
in such a way that the first 3 values returned by
<b><tt>map_color_rgb_alpha</tt></b> are the same as the values returned by
<b><tt>map_color_rgb</tt></b>.

<p>
Note that CMYK devices currently do not support variable opacity; alpha is
ignored on such devices.
</dl>

<dl>
<dt><b><tt>typedef&nbsp;enum&nbsp;{&nbsp;go_text,
go_graphics&nbsp;}&nbsp;graphic_object_type;&nbsp;int
(*get_alpha_bits)(P4(gx_device&nbsp;*dev,
graphic_object_type&nbsp;type))</tt></b> <b><em>[OPTIONAL]</em></b>
<dd>Return the number of alpha (opacity) bits that should be used in
rendering an object of the given type.  The default value is 1; the only
values allowed are 1, 2, and 4.
</dl>

<h2><a name="Drawing"></a>Drawing</h2>

<p>
All drawing operations use device coordinates and device color values.

<dl>
<dt><b><tt>int (*fill_rectangle)(P6(gx_device&nbsp;*, int&nbsp;x,
int&nbsp;y, int&nbsp;width, int&nbsp;height,
gx_color_index&nbsp;color))</tt></b>
<dd>Fill a rectangle with a color.  The set of pixels filled is {(px,py) |
x &lt;= px &lt; x + width and y &lt;= py &lt; y + height}.  In other words,
the point <em>(x,y)</em> is included in the rectangle, as are
<em>(x+w-1,y)</em>, <em>(x,y+h-1)</em>, and <em>(x+w-1,y+h-1)</em>, but
<b><em>not</em></b> <em>(x+w,y)</em>, <em>(x,y+h)</em>, or
<em>(x+w,y+h)</em>.  If <b><tt>width</tt></b>&nbsp;&lt;=&nbsp;0 or
height&nbsp;&lt;=&nbsp;0, <b><tt>fill_rectangle</tt></b> should return 0
without drawing anything.

<p>
Note that <b><tt>fill_rectangle</tt></b> is the only non-optional procedure
in the driver interface.
</dl>

<dl>
<b><tt>int (*draw_line)(P6(gx_device&nbsp;*, int&nbsp;x0, int&nbsp;y0,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -