add directory Linux-0.98
This commit is contained in:
552
Linux-0.98/Yggdrasil-0.98.3/usr/lib/ghostscript/doc/drivers.doc
Normal file
552
Linux-0.98/Yggdrasil-0.98.3/usr/lib/ghostscript/doc/drivers.doc
Normal file
@@ -0,0 +1,552 @@
|
||||
Copyright (C) 1989, 1990, 1991, 1992 Aladdin Enterprises.
|
||||
All rights reserved.
|
||||
Distributed by Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Ghostscript.
|
||||
|
||||
Ghostscript is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
|
||||
to anyone for the consequences of using it or for whether it serves any
|
||||
particular purpose or works at all, unless he says so in writing. Refer
|
||||
to the Ghostscript General Public License for full details.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute
|
||||
Ghostscript, but only under the conditions described in the Ghostscript
|
||||
General Public License. A copy of this license is supposed to have been
|
||||
given to you along with Ghostscript so you can know your rights and
|
||||
responsibilities. It should be in a file named COPYING. Among other
|
||||
things, the copyright notice and this notice must be preserved on all
|
||||
copies.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
This file, drivers.doc, describes the interface between Ghostscript and
|
||||
device drivers.
|
||||
|
||||
For an overview of Ghostscript and a list of the documentation files, see
|
||||
README.
|
||||
|
||||
********
|
||||
******** Adding a driver ********
|
||||
********
|
||||
|
||||
To add a driver to Ghostscript, all you need to do is edit devs.mak in
|
||||
two places. The first is the list of devices, in the section headed
|
||||
# -------------------------------- Catalog ------------------------------- #
|
||||
Pick a name for your device, say smurf, and add smurf to the list.
|
||||
(Device names must be 1 to 8 characters, consisting of only letters,
|
||||
digits, and underscores, of which the first character must be a letter.
|
||||
Case is significant: all current device names are lower case.)
|
||||
The second is the section headed
|
||||
# ---------------------------- Device drivers ---------------------------- #
|
||||
Suppose the files containing the smurf driver are called joe and fred.
|
||||
Then you should add the following lines:
|
||||
|
||||
# ------ The SMURF device ------ #
|
||||
|
||||
smurf_=joe.$(OBJ) fred.$(OBJ)
|
||||
smurf.dev: $(smurf_)
|
||||
$(SHP)gssetdev smurf $(smurf_)
|
||||
|
||||
joe.$(OBJ): joe.c ...and whatever it depends on
|
||||
|
||||
fred.$(OBJ): fred.c ...and whatever it depends on
|
||||
|
||||
If the smurf driver also needs special libraries, e.g., a library named
|
||||
gorf, then the gssetdev line should look like
|
||||
$(SHP)gssetdev smurf $(smurf_)
|
||||
$(SHP)gsaddmod smurf -lib gorf
|
||||
|
||||
********
|
||||
******** Driver structure ********
|
||||
********
|
||||
|
||||
A device is represented by a structure divided into three parts:
|
||||
|
||||
- procedures that are shared by all instances of each device;
|
||||
|
||||
- parameters that are present in all devices but may be different
|
||||
for each device or instance; and
|
||||
|
||||
- device-specific parameters that may be different for each instance.
|
||||
|
||||
Normally, the procedure structure is defined and initialized at compile
|
||||
time. A prototype of the parameter structure (including both generic and
|
||||
device-specific parameters) is defined and initialized at compile time,
|
||||
but is copied and filled in when an instance of the device is created.
|
||||
|
||||
The gx_device_common macro defines the common structure elements, with the
|
||||
intent that devices define and export a structure along the following
|
||||
lines:
|
||||
|
||||
typedef struct smurf_device_s {
|
||||
gx_device_common;
|
||||
... device-specific parameters ...
|
||||
} smurf_device;
|
||||
smurf_device gs_smurf_device = {
|
||||
sizeof(smurf_device), * params_size
|
||||
{ ... procedures ... }, * procs
|
||||
... generic parameter values ...
|
||||
... device-specific parameter values ...
|
||||
};
|
||||
|
||||
The device structure instance *must* have the name gs_smurf_device, where
|
||||
smurf is the device name used in devs.mak.
|
||||
|
||||
All the device procedures are called with the device as the first
|
||||
argument. Since each device type is actually a different structure type,
|
||||
the device procedures must be declared as taking a gx_device * as their
|
||||
first argument, and must cast it to smurf_device * internally. For
|
||||
example, in the code for the "memory" device, the first argument to all
|
||||
routines is called dev, but the routines actually use md to reference
|
||||
elements of the full structure, by virtue of the definition
|
||||
|
||||
#define md ((gx_device_memory *)dev)
|
||||
|
||||
(This is a cheap version of "object-oriented" programming: in C++, for
|
||||
example, the cast would be unnecessary, and in fact the procedure table
|
||||
would be constructed by the compiler.)
|
||||
|
||||
Structure definition
|
||||
--------------------
|
||||
|
||||
This essentially duplicates the structure definition in gxdevice.h.
|
||||
|
||||
typedef struct gx_device_s {
|
||||
int params_size; /* size of this structure */
|
||||
gx_device_procs *procs; /* pointer to procedure structure */
|
||||
char *name; /* the device name */
|
||||
int width; /* width in pixels */
|
||||
int height; /* height in pixels */
|
||||
float x_pixels_per_inch; /* x density */
|
||||
float y_pixels_per_inch; /* y density */
|
||||
gs_rect margin_inches; /* margins around imageable area, */
|
||||
/* in inches */
|
||||
gx_device_color_info color_info; /* color information */
|
||||
int is_open; /* true if device has been opened */
|
||||
} gx_device;
|
||||
|
||||
The name in the structure should be the same as the name in devs.mak.
|
||||
|
||||
gx_device_common is a macro consisting of just the element definitions.
|
||||
|
||||
If for any reason you need to change the definition of the basic device
|
||||
structure, or add procedures, you must change the following places:
|
||||
|
||||
- This document and NEWS (if you want to keep the
|
||||
documentation up to date).
|
||||
- The definition of gx_device_common and/or the procedures
|
||||
in gxdevice.h.
|
||||
- The null device in gsdevice.c.
|
||||
- The tracing "device" in gstdev.c.
|
||||
- The "memory" devices in gdevmem.h and gdevmem*.c.
|
||||
- The command list "device" in gxclist.c.
|
||||
- The clip list accumulation and clipping "devices" in gxcpath.c.
|
||||
- The generic printer device macros in gdevprn.h.
|
||||
- The generic printer device code in gdevprn.c.
|
||||
- All the real devices in the standard Ghostscript distribution,
|
||||
as listed in devs.mak. (Most of the printer devices are
|
||||
created with the macros in gdevprn.h, so you may not have to
|
||||
edit the source code for them.)
|
||||
- Any other drivers you have that aren't part of the standard
|
||||
Ghostscript distribution.
|
||||
|
||||
You may also have to change the code for gx_default_get_props and/or
|
||||
gx_default_put_props (in gsdevice.c).
|
||||
|
||||
********
|
||||
******** Types and coordinates ********
|
||||
********
|
||||
|
||||
Coordinate system
|
||||
-----------------
|
||||
|
||||
Since each driver specifies the initial transformation from user to device
|
||||
coordinates, the driver can use any coordinate system it wants, as long as
|
||||
a device coordinate will fit in an int. (This is only an issue on MS-DOS
|
||||
systems, where ints are only 16 bits. User coordinates are represented as
|
||||
floats.) Typically the coordinate system will have (0,0) in the upper
|
||||
left corner, with X increasing to the right and Y increasing toward the
|
||||
bottom. This happens to be the coordinate system that all the currently
|
||||
supported devices use. However, there is supposed to be nothing in the
|
||||
rest of Ghostscript that assumes this.
|
||||
|
||||
Drivers must check (and, if necessary, clip) the coordinate parameters
|
||||
given to them: they should not assume the coordinates will be in bounds.
|
||||
|
||||
Color definition
|
||||
----------------
|
||||
|
||||
Ghostscript represents colors internally as RGB values. In communicating
|
||||
with devices, however, it assumes that each device has a palette of colors
|
||||
identified by integers (to be precise, elements of type gx_color_index).
|
||||
Drivers may provide a uniformly spaced gray ramp or color cube for
|
||||
halftoning, or they may do their own color approximation, or both.
|
||||
|
||||
The color_info member of the device structure defines the color and
|
||||
gray-scale capabilities of the device. Its type is defined as follows:
|
||||
|
||||
typedef struct gx_device_color_info_s {
|
||||
int num_components; /* 1 = gray only, 3 = RGB, */
|
||||
/* 4 = CMYK (not supported) */
|
||||
int depth; /* # of bits per pixel */
|
||||
gx_color_value max_gray; /* # of distinct gray levels -1 */
|
||||
gx_color_value max_rgb; /* # of distinct color levels -1 */
|
||||
/* (only relevant if num_comp. > 1) */
|
||||
gx_color_value dither_gray; /* size of gray ramp for halftoning */
|
||||
gx_color_value dither_rgb; /* size of color cube ditto */
|
||||
/* (only relevant if num_comp. > 1) */
|
||||
} gx_device_color_info;
|
||||
|
||||
The following macros (in gxdevice.h) provide convenient shorthands for
|
||||
initializing this structure for ordinary black-and-white or color devices:
|
||||
|
||||
#define dci_black_and_white { 1, 1, 1, 0, 2, 0 }
|
||||
#define dci_color(depth,maxv,dither) { 3, depth, maxv, maxv, dither, dither }
|
||||
|
||||
The idea is that a device has a certain number of gray levels (max_gray
|
||||
+1) and a certain number of colors (max_rgb +1) that it can produce
|
||||
directly. When Ghostscript wants to render a given RGB color as a device
|
||||
color, it first tests whether the color is a gray level. (If
|
||||
num_components is 1, it converts all colors to gray levels.) If so:
|
||||
|
||||
- If max_gray is large (>= 31), Ghostscript asks the device to
|
||||
approximate the gray level directly. If the device returns a
|
||||
gx_color_value, Ghostscript uses it. Otherwise, Ghostscript assumes that
|
||||
the device can represent dither_gray distinct gray levels, equally spaced
|
||||
along the diagonal of the color cube, and uses the two nearest ones to the
|
||||
desired color for halftoning.
|
||||
|
||||
If the color is not a gray level:
|
||||
|
||||
- If max_rgb is large (>= 31), Ghostscript asks the device to
|
||||
approximate the color directly. If the device returns a
|
||||
gx_color_value, Ghostscript uses it. Otherwise, Ghostscript assumes
|
||||
that the device can represent dither_rgb * dither_rgb * dither_rgb
|
||||
distinct colors, equally spaced throughout the color cube, and uses
|
||||
two of the nearest ones to the desired color for halftoning.
|
||||
|
||||
Types
|
||||
-----
|
||||
|
||||
Here is a brief explanation of the various types that appear as parameters
|
||||
or results of the drivers.
|
||||
|
||||
gx_color_value (defined in gxdevice.h)
|
||||
|
||||
This is the type used to represent RGB color values. It is
|
||||
currently equivalent to unsigned short. However, Ghostscript may use less
|
||||
than the full range of the type to represent color values:
|
||||
gx_color_value_bits is the number of bits actually used, and
|
||||
gx_max_color_value is the maximum value (equal to
|
||||
2^gx_max_color_value_bits - 1).
|
||||
|
||||
gx_device (defined in gxdevice.h)
|
||||
|
||||
This is the device structure, as explained above.
|
||||
|
||||
gs_matrix (defined in gsmatrix.h)
|
||||
|
||||
This is a 2-D homogenous coordinate transformation matrix, used by
|
||||
many Ghostscript operators.
|
||||
|
||||
gx_color_index (defined in gxdevice.h)
|
||||
|
||||
This is meant to be whatever the driver uses to represent a device
|
||||
color. For example, it might be an index in a color map. Ghostscript
|
||||
doesn't ever do any computations with these values: it gets them from
|
||||
map_rgb_color and hands them back as arguments to several other
|
||||
procedures. The special value gx_no_color_index (defined as
|
||||
(gx_color_index)(-1)) means "transparent" for some of the procedures. The
|
||||
type definition is simply:
|
||||
|
||||
typedef unsigned long gx_color_index;
|
||||
|
||||
gs_prop_item (defined in gsprops.h)
|
||||
|
||||
This is an element of a property list, which is used to read and
|
||||
set attributes in a device. See the comments in gsprops.h, and the
|
||||
description of the get_props and put_props procedures below, for more
|
||||
detail.
|
||||
|
||||
gx_bitmap (defined in gxbitmap.h)
|
||||
|
||||
This structure type represents a bitmap to be used as a tile for
|
||||
filling a region (rectangle). Here is a copy of the relevant part of the
|
||||
file:
|
||||
|
||||
/*
|
||||
* Structure for describing stored bitmaps.
|
||||
* Bitmaps are stored bit-big-endian (i.e., the 2^7 bit of the first
|
||||
* byte corresponds to x=0), as a sequence of bytes (i.e., you can't
|
||||
* do word-oriented operations on them if you're on a little-endian
|
||||
* platform like the Intel 80x86 or VAX). Each scan line must start on
|
||||
* a (32-bit) word boundary, and hence is padded to a word boundary,
|
||||
* although this should rarely be of concern, since the raster and width
|
||||
* are specified individually. The first scan line corresponds to y=0
|
||||
* in whatever coordinate system is relevant.
|
||||
*
|
||||
* For bitmaps used as halftone tiles, we may replicate the tile in
|
||||
* X and/or Y, but it is still valuable to know the true tile dimensions.
|
||||
*/
|
||||
typedef struct gx_bitmap_s {
|
||||
byte *data;
|
||||
int raster; /* bytes per scan line */
|
||||
gs_int_point size; /* width, height */
|
||||
gx_bitmap_id id;
|
||||
ushort rep_width, rep_height; /* true size of tile */
|
||||
} gx_bitmap;
|
||||
|
||||
********
|
||||
******** Driver procedures ********
|
||||
********
|
||||
|
||||
All the procedures that return int results return 0 on success, or an
|
||||
appropriate negative error code in the case of error conditions. The
|
||||
error codes are defined in gserrors.h. The relevant ones for drivers
|
||||
are as follows:
|
||||
|
||||
gs_error_invalidfileaccess
|
||||
An attempt to open a file failed.
|
||||
|
||||
gs_error_limitcheck
|
||||
An otherwise valid parameter value was too large for
|
||||
the implementation.
|
||||
|
||||
gs_error_rangecheck
|
||||
A parameter was outside the valid range.
|
||||
|
||||
gs_error_VMerror
|
||||
An attempt to allocate memory failed. (If this
|
||||
happens, the procedure should release all memory it
|
||||
allocated before it returns.)
|
||||
|
||||
If a driver does return an error, it should use the return_error
|
||||
macro rather than a simple return statement, e.g.,
|
||||
|
||||
return_error(gs_error_VMerror);
|
||||
|
||||
This macro is defined in gx.h, which is automatically included by
|
||||
gdevprn.h but not by gserrors.h.
|
||||
|
||||
Most procedures are optional. If a device doesn't supply an optional
|
||||
procedure proc, the entry in the procedure structure should be
|
||||
gx_default_proc, e.g. gx_default_tile_rectangle. The device procedure
|
||||
must also call this procedure if it doesn't implement the function for
|
||||
particular values of the arguments.
|
||||
|
||||
Open/close/sync
|
||||
---------------
|
||||
|
||||
int (*open_device)(P1(gx_device *)) [OPTIONAL]
|
||||
|
||||
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.
|
||||
|
||||
void (*get_initial_matrix)(P2(gx_device *, gs_matrix *)) [OPTIONAL]
|
||||
|
||||
Construct the initial transformation matrix mapping user
|
||||
coordinates (nominally 1/72" per unit) to device coordinates. The default
|
||||
procedure computes this from width, height, and x/y_pixels_per_inch on the
|
||||
assumption that the origin is in the upper left corner, i.e.
|
||||
xx = x_pixels_per_inch/72, xy = 0,
|
||||
yx = 0, yy = -y_pixels_per_inch/72,
|
||||
tx = 0, ty = height.
|
||||
|
||||
int (*sync_output)(P1(gx_device *)) [OPTIONAL]
|
||||
|
||||
Synchronize the device. If any output to the device has been
|
||||
buffered, send / write it now. Note that this may be called several times
|
||||
in the process of constructing a page, so printer drivers should NOT
|
||||
implement this by printing the page. The default implementation does
|
||||
nothing.
|
||||
|
||||
int (*output_page)(P3(gx_device *, int num_copies, int flush)) [OPTIONAL]
|
||||
|
||||
Output a fully composed page to the device. The num_copies
|
||||
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 flush argument is true for showpage, false for
|
||||
copypage. The default definition just calls sync_output. Printer drivers
|
||||
should implement this by printing and ejecting the page.
|
||||
|
||||
int (*close_device)(P1(gx_device *)) [OPTIONAL]
|
||||
|
||||
Close the device: release any associated resources. After this,
|
||||
output to the device is no longer allowed. The default implementation
|
||||
does nothing.
|
||||
|
||||
Color mapping
|
||||
-------------
|
||||
|
||||
gx_color_index (*map_rgb_color)(P4(gx_device *, gx_color_value red,
|
||||
gx_color_value green, gx_color_value blue)) [OPTIONAL]
|
||||
|
||||
Map a RGB color to a device color. The range of legal values of
|
||||
the RGB arguments is 0 to gx_max_color_value. The default algorithm
|
||||
returns 1 if any of the values exceeds gx_max_color_value/2, 0 otherwise.
|
||||
|
||||
Ghostscript assumes that for devices that have color capability
|
||||
(i.e., color_info.num_components > 1), map_rgb_color returns a color index
|
||||
for a gray level (as opposed to a non-gray color) iff red = green = blue.
|
||||
|
||||
int (*map_color_rgb)(P3(gx_device *, gx_color_index color,
|
||||
gx_color_value rgb[3])) [OPTIONAL]
|
||||
|
||||
Map a device color code to RGB values. The default algorithm
|
||||
returns (0 if color==0 else gx_max_color_value) for all three components.
|
||||
|
||||
Drawing
|
||||
-------
|
||||
|
||||
All drawing operations use device coordinates and device color values.
|
||||
|
||||
int (*fill_rectangle)(P6(gx_device *, int x, int y,
|
||||
int width, int height, gx_color_index color))
|
||||
|
||||
Fill a rectangle with a color. The set of pixels filled is
|
||||
{(px,py) | x <= px < x + width and y <= py < y + height}. In other words,
|
||||
the point (x,y) is included in the rectangle, as are (x+w-1,y), (x,y+h-1),
|
||||
and (x+w-1,y+h-1), but *not* (x+w,y), (x,y+h), or (x+w,y+h). If width <=
|
||||
0 or height <= 0, fill_rectangle should return 0 without drawing anything.
|
||||
|
||||
int (*draw_line)(P6(gx_device *, int x0, int y0, int x1, int y1,
|
||||
gx_color_index color)) [OPTIONAL]
|
||||
|
||||
Draw a minimum-thickness line from (x0,y0) to (x1,y1). The
|
||||
precise set of points to be filled is defined as follows. First, if y1 <
|
||||
y0, swap (x0,y0) and (x1,y1). Then the line includes the point (x0,y0)
|
||||
but not the point (x1,y1). If x0=x1 and y0=y1, draw_line should return 0
|
||||
without drawing anything.
|
||||
|
||||
Bitmap imaging
|
||||
--------------
|
||||
|
||||
Bitmap (or pixmap) images are stored in memory in a nearly standard way.
|
||||
The first byte corresponds to (0,0) in the image coordinate system: bits
|
||||
(or polybit color values) are packed into it left-to-right. There may be
|
||||
padding at the end of each scan line: the distance from one scan line to
|
||||
the next is always passed as an explicit argument.
|
||||
|
||||
int (*copy_mono)(P11(gx_device *, const unsigned char *data, int data_x,
|
||||
int raster, gx_bitmap_id id, int x, int y, int width, int height,
|
||||
gx_color_index color0, gx_color_index color1))
|
||||
|
||||
Copy a monochrome image (similar to the PostScript image
|
||||
operator). Each scan line is raster bytes wide. Copying begins at
|
||||
(data_x,0) and transfers a rectangle of the given width at height to the
|
||||
device at device coordinate (x,y). (If the transfer should start at some
|
||||
non-zero y value in the data, the caller can adjust the data address by
|
||||
the appropriate multiple of the raster.) The copying operation writes
|
||||
device color color0 at each 0-bit, and color1 at each 1-bit: if color0 or
|
||||
color1 is gx_no_color_index, the device pixel is unaffected if the image
|
||||
bit is 0 or 1 respectively. If id is different from gx_no_bitmap_id, it
|
||||
identifies the bitmap contents unambiguously; a call with the same id will
|
||||
always have the same data, raster, and data contents.
|
||||
|
||||
This operation is the workhorse for text display in Ghostscript,
|
||||
so implementing it efficiently is very important.
|
||||
|
||||
int (*tile_rectangle)(P10(gx_device *, const gx_bitmap *tile,
|
||||
int x, int y, int width, int height,
|
||||
gx_color_index color0, gx_color_index color1,
|
||||
int phase_x, int phase_y)) [OPTIONAL]
|
||||
|
||||
Tile a rectangle. Tiling consists of doing multiple copy_mono
|
||||
operations to fill the rectangle with copies of the tile. The tiles are
|
||||
aligned with the device coordinate system, to avoid "seams".
|
||||
Specifically, the (phase_x, phase_y) point of the tile is aligned with the
|
||||
origin of the device coordinate system. (Note that this is backwards from
|
||||
the PostScript definition of halftone phase.) phase_x and phase_y are
|
||||
guaranteed to be in the range [0..tile->width) and [0..tile->height)
|
||||
respectively.
|
||||
|
||||
If color0 and color1 are both gx_no_color_index, then the tile is
|
||||
a color pixmap, not a bitmap: see the next section.
|
||||
|
||||
Pixmap imaging
|
||||
--------------
|
||||
|
||||
Pixmaps are just like bitmaps, except that each pixel occupies more than
|
||||
one bit. All the bits for each pixel are grouped together (this is
|
||||
sometimes called "chunky" or "Z" format). The number of bits per pixel is
|
||||
given by the color_info.depth parameter in the device structure: the legal
|
||||
values are 1, 2, 4, 8, 16, 24, or 32. The pixel values are device color
|
||||
codes (i.e., whatever it is that map_rgb_color returns).
|
||||
|
||||
int (*copy_color)(P9(gx_device *, const unsigned char *data, int data_x,
|
||||
int raster, gx_bitmap_id id, int x, int y, int width, int height))
|
||||
|
||||
Copy a color image with multiple bits per pixel. The raster is in
|
||||
bytes, but x and width are in pixels, not bits. If the device doesn't
|
||||
actually support color, this is OPTIONAL; the default is equivalent to
|
||||
copy_mono with color0 = 0 and color1 = 1. If id is different from
|
||||
gx_no_bitmap_id, it identifies the bitmap contents unambiguously; a call
|
||||
with the same id will always have the same data, raster, and data
|
||||
contents.
|
||||
|
||||
tile_rectangle can also take colored tiles. This is indicated by the
|
||||
color0 and color1 arguments both being gx_no_color_index. In this case,
|
||||
as for copy_color, the raster and height in the "bitmap" are interpreted
|
||||
as for real bitmaps, but the x and width are in pixels, not bits.
|
||||
|
||||
Reading bits back
|
||||
-----------------
|
||||
|
||||
int (*get_bits)(P5(gx_device *, int y,
|
||||
byte *str, unsigned int size, int pad_to_word)) [OPTIONAL]
|
||||
|
||||
Read bits back from the device into the area of size bytes
|
||||
starting at str, starting with scan line y. If the bits cannot be read
|
||||
back (e.g., from a printer), return -1; otherwise return a value as
|
||||
described below. The contents of the bits beyond the last valid bit in
|
||||
the scan line (as defined by the device width) are unpredictable.
|
||||
|
||||
If pad_to_word is 0, scan lines are only padded to a byte boundary; the
|
||||
normal return value is 0.
|
||||
|
||||
If pad_to_word is 1, scan lines are padded to a multiple of 4 bytes; the
|
||||
normal return value is 0.
|
||||
|
||||
If pad_to_word is -1, scan lines are padded to a multiple of 4 bytes, and
|
||||
in addition, the bytes may be swapped within a word. The normal return
|
||||
value is 0 if no byte swapping is needed, 2 if bytes must be swapped
|
||||
within a 16-bit word, or 4 if bytes must be swapped within a 32-bit word.
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
Devices may have an open-ended set of properties, which are simply pairs
|
||||
consisting of a name and a value. The value may be of various types:
|
||||
integer, boolean, float, string, array of integer, or array of float.
|
||||
|
||||
Property lists are somewhat complex. If your device has properties beyond
|
||||
those of a straightforward display or printer, we strongly advise using
|
||||
the code for the default implementation of get_props and put_props in
|
||||
gsdevice.c as a model for your own code.
|
||||
|
||||
int (*get_props)(P2(gx_device *dev, gs_prop_item *plist)) [OPTIONAL]
|
||||
|
||||
Read all the properties of the device into the property list at
|
||||
plist. Return the number of properties. See gsprops.h for more details,
|
||||
gx_default_get_props in gsdevice.c for an example.
|
||||
|
||||
If plist is NULL, just return the number of properties plus the
|
||||
total number of elements in all array-valued properties. This is how the
|
||||
getdeviceprops operator finds out how much storage to allocate for the
|
||||
property list.
|
||||
|
||||
int (*put_props)(P3(gx_device *dev, gs_prop_item *plist,
|
||||
int count)) [OPTIONAL]
|
||||
|
||||
Set the properties of the device from the property list at plist.
|
||||
Return 0 if everything was OK, an error code
|
||||
(gs_error_undefined/typecheck/rangecheck/limitcheck) if some property had
|
||||
an invalid type or out-of-range value. See gsprops.h for more details,
|
||||
gx_default_put_props in gsdevice.c for an example.
|
||||
|
||||
Changing device properties may require closing the device and
|
||||
reopening it. If this is the case, the put_props procedure should
|
||||
just close the device; a higher-level routine (gs_putdeviceprops)
|
||||
will reopen it.
|
||||
Reference in New Issue
Block a user