'\"!  tbl | mmdoc
.if n .pH port.chap3 @(#)chap3	40.1
.ig
imagen dc 8/31/89
docformat -c -s4 -dqm4 -p1 chap3
..
.BK "Shapes Porting Guide"
.CH "Porting at the Screen Object Level" "3"
.H 1 "Porting at the Screen Object Level" 
.H 2 "Introduction"
.P
If you are porting to a framebuffer that is similar
to one of Sun's framebuffers,
you might want to port at a level very close to the
pixel rendering level to take advantage of the performance
and size optimizations built into Sun's rendering code.
However, porting at this level requires that you learn
the intimate details of the rendering code.
If you already have X11 rendering code or don't want
to spend the time learning the details of Sun's implementation,
you could port at the level of the screen object.
.P
This chapter will be useful to you regardless of the
level you choose for porting.
.H 2 "The Screen Object"
.P
The Shapes screen object centralizes the device-specific
information and control for each supported graphics device type.
This object must be initialized whenever the first raster
is created on the device,
usually at the time the device is initialized.
(The initialization code is in the xxxRas.c device specific
file for the device.)
The following screen object attributes are defined in file sh_SCR.ah:
.PC
Unsgn8   SCR_NAME[FB_NAME_SIZE]; /* frame buffer name */
Unsgn8   SCR_PHYS_DEV;	         /* physical device (Scr_Phys ofs) */
Unsgn8   SCR_VIRT_DEV;           /* virtual device (Scr_Virt ofs) */
Unsgn8   SCR_DEPTH;              /* screen depth */
Unsgn8   scr_depth_index         /* screen depth index */
Unsgn8   SCR_CMAP_SIZE;	         /* color map size */
Unsgn16  SCR_LINEBYTES;	         /* bytes per scan line */
Unsgn16  SCR_WIDTH;              /* screen width in pixels */
Unsgn16  SCR_HEIGHT;             /* screen height in pixels */
int      SCR_DEV_FD;             /* file descriptor of open device */
int      SCR_WIN_FD;             /* Sunview window file desc. of fb */
Unsgn32  SCR_MAX_PLANE_MASK;	 /* maximum plane enable value */
Unsgn8   *SCR_RAS_START;         /* start of framebuffer memory */
CMAP     SCR_CMAP_INDEX;         /* indexed color map */
CMAP     SCR_CMAP_RGB;           /* direct color color map */
RND_FUNC *SCR_PATH_FUN;          /* path traversal functions */
RND_FUNC *SCR_STROKE_FUN;        /* vector/curve rendering functions */
RND_FUNC *SCR_FILL_FUN;          /* area fill rendering functions */
RND_FUNC *SCR_COPY_FUN;          /* raster copy rendering functions */
RND_FUNC *SCR_GLYPH_FUN;         /* glyph rendering functions */
.\" begin new page
.SF
\f3SCR_NAME\f1
.P
The name that the operating system will recognize when
opening the device.
.sp
\f3SCR_PHYS_DEV
.br
\f3SCR_VIRT_DEV\f1
.P
Devices from the list of devices in file sh_scr_dev.h
(which must be updated when new devices are added).
This is how Shapes differentiates one type of device
from another.
Usually there is only one SCR_PHYS_DEV type,
but with some devices
(like the Sun cg4 frame buffer),
there can be several SCR_VIRT_DEV types for a
single SCR_PHYS_DEV.
SCR_VIRT_DEV types
generally mimic one or more SCR_PHYS_DEV.
Each
SCR_VIRT_DEV type will have a unique screen object
allocated for it even though they may all be on the
same physical device.
.P
\f3SCR_DEPTH\f1
.P
The bit depth of a pixel on this screen.
.P
\f3scr_depth_index\f1
.P
An index value directly related to the screen pixel depth,
which is used during dispatch vector
determination and device specific dispatching.
Its possible values are defined in /include/sh_RAS.h,
which currently includes RAS_DEPTH_1,
RAS_DEPTH_8, and RAS_DEPTH_32.
If you plan to add support for a new pixel depth,
you should define a new RAS_DEPTH_XX value.
Only code in the /dd directory and its subdirectories
must be altered to handle the new depth value.
.P
\f3SCR_CMAP_SIZE\f1
.P
The maximum number of color map entries available
for this device.
.P
\f3SCR_LINEBYTES
.P
The number of bytes (padded) per scanline on this device.
.P
\f3SCR_WIDTH\f1
.P
The number of pixels per scanline on this device.
.P
\f3SCR_HEIGHT\f1
.P
The number of scanlines on this device.
.P
\f3SCR_DEV_FD\f1
.P
The location of the Unix file descriptor is saved for
the device while it is open.
.P
\f3SCR_WIN_FD\f1
.P
The location of the  Sunview1 window file descriptor
is saved for the device
(this is used for Sunview1 backward compatibility).
.\" begin new page
.P
\f3SCR_MAX_PLANE_MASK\f1
.P
The maximum plane enable value for the device
(so far this is the same as the number of bits in
the pixel depth for the device except for 32 bit
deep devices.)
.P
\f3*SCR_RAS_START\f1
.P
The address of the first pixel in the frame buffer
when accessing it as a dumb frame buffer.
Currently, Shapes assumes that when it needs to
read or write pixels on the screen to support
some function not supported by hardware,
it can get to them using this address,
and that complete pixels
(all bits in SCR_DEPTH)
can be accessed via this method
(especially when reading pixels).
.P
\f3SCR_CMAP_INDEX\f1
.P
The indexed color map associated with the
screen object when one exists.
.P
\f3SCR_CMAP_RGB\f1
.P
The RGB color map associated with the screen object
when one exists.
.P
\f3*SCR_PATH_FUN\f1
.P
The dispatch vector for all Shapes path operators
for this device.
Since path operators do not render
pixels directly on dumb frame buffers, this dispatch
vector needs no device-specific support for a dumb
frame buffer port.
The generic dispatch vector can be used here
(sh_fb_path_fun).
.P
\f3*SCR_STROKE_FUN\f1
.P
The dispatch vector for the vector and curve
rendering functions for the device.
This dispatch vector should be initialized to
point to the device-specific dispatch table
sh_xxx_stroke_fun[] in the xxxRas.c file for your device.
.P
\f3*SCR_FILL_FUN\f1
.P
The dispatch vector for the area fill rendering
functions for the device.
This dispatch vector should be initialized to
point to a device-specific dispatch table
sh_xxx_fill_fun[] in the xxxRas.c file for your device.
.P
\f3*SCR_COPY_FUN\f1
.P
The dispatch vector for the raster copy rendering
functions for the device.
This dispatch vector should be initialized to
point to a device-specific dispatch table
sh_xxx_copy_fun[] in the xxxRas.c file for your device.
.P
\f3*SCR_GLYPH_FUN\f1
.P
The dispatch vector for the glyph rendering
functions for the device.
This dispatch vector should be initialized to
point to a device-specific dispatch table
sh_xxx_glyph_fun[] in the xxxRas.c file for your device.
.H 2 "Dispatch Tables"
.P
The rendering dispatch tables live in the corresponding
xxxRas.c file for the device.
The rendering dispatch vectors in the screen object
(*SCR_STROKE_FUN, *SCR_FILL_FUN,
*SCR_COPY_FUN, and *SCR_GLYPH_FUN)
are initialized to point to the corresponding table
described below when the sh_init_xxx(scr) routine in
xxxRas.c is executed during device initialization.
Additionally, xxxRas.c should contain a sh_xxx_ops_ras
dispatch table.
Some of the raster operators
(display_raster, image_raster, points_raster, etc.)
support device-dependent versions by using the sh_xxx_ops_ras table.
.H 2 "Stroke Functions"
.PC
RND_FUNC             sh_xxx_stroke_fun[] = {
                     /* clipped to rectangle */
                     xxx_fill_shape,
                     xxx_vec_shape,
                     sh_fb_render_curve_2d,
                     /* clipped to complex clip shape */
                     xxx_fill_shape,
                     xxx_vec_shape,
                     sh_fb_render_curve_2d };
.SF
The stroke function dispatch table generally supports
three kinds of stroke rendering functions.
They also include filled stroke primitives
(like patterned, stippled, or textured lines),
vectors, and curves.
While it is not absolutely necessary to do so,
Shapes currently supports two sets of these dispatch vectors.
A routine is called from the first set when rendering
will be clipped to a single rectangle,
from the second set when rendering will be clipped to a complex,
multiple rectangle clip shape.
Thus, this dispatch table has six entries.
.P
For most dumb frame buffer implementations,
the xxx_vec_shape entry in the stroke rendering dispatch
tables is actually a dispatch vector to another table
that contains dispatch table entries for each of the
four fill styles:
.PC
static	RND_FUNC             xxx_vec_shape[] = {
                             sh_xxx_Vect,
                             sh_fb_L2Ds,
                             sh_fb_L2Ds,
                             sh_fb_L2Ds };
.SF
The sh_xxx_Vect routine directly renders high performance
thin vectors into the frame buffer for both a single
rectangular clip shape and a complex clip shape.
The other routine first generates a shape object boundary
description for the vector
(as does the curve routine),
then eventually calls one of the fill routines described
below to do the actual pixel rendering.
Thus, sh_fb_L2Ds is actually device-independent;
you may use the existing generic routine for fill styles,
and need only directly support the thin solid vector
rendering routine for your device.
You also need not directly support curve rendering for
your device,
sh_fb_render_curve_2d will suffice.
.H 2 "Fill Functions"
.PC
RND_FUNC                sh_xxx_fill_fun[] = {
                        /* clipped to rectangle */
                        xxx_fill_shape,
                        NULL,
                        sh_fb_render_curve_2d,
                        sh_fb_Area_Shape,
                        /* clipped to complex clip shape */
                        xxx_fill_shape,
                        NULL,
                        sh_fb_render_curve_2d,
                        sh_fb_A2Ds };
.SF
The fill function dispatch table generally supports
four kinds of fill rendering functions:\ \&
filled shapes, filled vectors
(usually just a place holder),
filled curves, and filled polygon edge lists.
Again, Shapes currently supports two sets of these dispatch vectors,
one set for rendering clipped to a single rectangle
and another set for rendering clipped to a complex clip shape,
making a total of eight entries in this table.
The existing generic routines can be used for polygon
edge list to shape object conversion for all
frame buffer implementations;
thus, sh_fb_Area_Shape() can be used for the rectangular
clipped polygon fill entry,
and sh_fb_A2Ds() can be used for the complex clip
shape polygon fill entry.
The generic polygon edge list routines will eventually
call the other entries in this table to do their actual
pixel rendering.
The remainder of the table should contain your device
specific entries for filling
(for most frame buffers these entries are duplicates
of the corresponding stroke function table entries).
Each of entries in the fill dispatch table must support
all four fill styles
(CTX_FILL_SOLID, CTX_FILL_TEXTURED, CTX_FILL_OPAQUE_STIPPLED,
and CTX_FILL_STIPPLED).
Since the primitives to be rendered are ultimately
described as shape objects when rendering into dumb frame buffers,
routines for filling shape objects using each of the
four fill styles are all that are absolutely necessary to support.
.P
For most dumb frame buffer implementations,
the xxx_fill_shape entry in the stroke and fill rendering
dispatch tables is actually a dispatch vector to another
table that contains dispatch table entries for each
of the four fill styles:
.PC
static	RND_FUNC             xxx_fill_shape[] = {
                             sh_xxx_FLRSs,
                             sh_xxx_TXRSs,
                             sh_xxx_OSRSs,
                             sh_xxx_STRSs };
.SF
Thus, one of these four routines is ultimately used to
render pixels onto the device depending on the fill
style to be used.
The destination is always described using a shape
object boundary description.
You may notice that the actual table for most frame
buffers is made up of multiple copies of these entries.
Only the first ten copies of each entry are ever referenced,
although there is space in the table for each entry
to be duplicated sixteen times.
The first five of the duplicate entries are referenced
whenever a plane enable mask can be ignored
during pixel rendering;
the second five are referenced whenever a plane enable
mask must be used.
Thus, you can force Shapes to use different rendering
routines depending on whether a plane enable mask is
active or not if you have produced such specialized
rendering routines.
Within each set of five duplicate entries,
Shapes further differentiates based on the CTX_ROP value.
The first entry is for the most common type of rendering
(CTX_ROP_DRAW).
The remaining entries can be used to differentiate between
other CTX_ROP values that you may want to special case,
although you would have to learn more about Shapes internals
if you decide you want to use them.
Currently, it is enough to just have all other CTX_ROP
values supported by the second entry.
As you can see,
Shapes no longer uses these tables extensively to differentiate
rendering routines based on CTX_ROP.
Doing so caused an excessive duplication of rendering code.
CTX_ROP_DRAW is still special-cased in some places.
.H 2 "Copy Functions"
.PC
RND_FUNC         sh_xxx_copy_fun[] = { sh_xxx_CPRSs };
.SF
Most frame buffers have only one raster copy function.
It can be used for copying whether the clip shape is
a simple rectangle or a complex clip shape,
since a shape object boundary description is
always produced for the destination.
.H 2 "Glyph Functions"
.PC
RND_FUNC          sh_xxx_glyph_fun[] = {
                  sh_xxx_FLGLs___,
                  sh_xxx_TXGLs___,		
                  sh_xxx_OSGLs___,		
                  sh_xxx_STGLs___	};
.SF
All four fill styles must also be supported for glyph rendering,
although they can all be defined in terms of a combination
of solid glyph and raster fill style rendering.
Thus, only solid glyph rendering need be fully supported
down to the pixel rendering level.
Glyph rendering is always clipped to a shape object boundary description.
.H 2 "Other Device-Specific Files"
.P
You will need to support the image scaling and
transformation functions as exist in dd/mem/memImS.ace,
and the point list rendering function as in dd/mem/memPtS.ace,
but these files work only on memory rasters and
will need modified only if your device uses a new
pixel depth or new memory architecture.
.P
xxxRas.c contains the device specific opening,
closing, initialization, dispatch vectors,
and color map installation routines for each specific
device type.
You will also need to understand how to register your
device with Shapes at system initialization time.
You will have to add code to dd/init.c to do this.
.P
Also, you will need to understand what is going on in
the device specific m1Cmap.c, m8Cmap.c, or m32Cmap.c files,
whichever comes closest to the pixel depth of your new device.
You may also need to add a similar file to provide color
map support for your device if it has a different pixel
depth than those currently supported and cannot be accommodated
by the current code.
.P
The existing generic cursor code will always work on your device,
although it may not work optimally.
If you have a device-specific cursor implementation,
you should look at the code in cg4Ras.c.
.H 2 "Rendering Routine Descriptions"
.P
Duplicating the following rendering routines should
be all that is necessary for a minimal port to a dumb
frame buffer.
All of the rendering routines get their rendering attributes
from either a global rendering attribute structure FBATTR sh_fb_attrs
(defined in fb_render.h) or a more locally-produced
version of that data structure.
A rendering attribute prefixed with FB_ refers to an
attribute in the global structure.
.H 2 "Vectors"
.P
An example of thin solid vector rendering can be found
in dd/mem/memVcS.ace:
.PC
sh_fb_Vect(ras, p)
	RASTER		ras;		/* destination raster */
	POINT_B2D	*p;		/* new vector end point */
.SF
Draws a vector from the current point (FB_pen) to the
new end point (p) clipped to the raster clip shape.
It must support plane enables and all rops for 0 width
solid vectors.
It also must support the CTX_CAP_NOTLAST line cap attribute.
This routine handles multiple pixel depths,
but your routine need support only the pixel depth of
your device.
.H 2 "Area Filling"
.P
An example of solid area filling can be found in dd/mem/memFlS.ace:
.PC
/* sh_mem_FLRSs */
sh_mem_fill_shape(ras, attrs, shape)
	RASTER		ras;		/* destination raster */
	FBATTR		*attrs;		/* rendering attributes */
	SHAPE		shape;		/* fill area shape object description*/
.SF
This routine solid fills the area described by shape
(which has been completely clipped)
with the color in attrs->col using attrs->rop and attrs->plane_enable
as the raster op and plane enable values.
It supports all rops.
It also supports several pixel depths,
although your version need only support the pixel depth
of your device.
Shapes observes the following convention when rendering
into any shape object:\ \&
the last pixel of each scanline is not rendered,
and the last scanline of each rectangle within the shape
object is not rendered.
The routine name gets converted into
sh_mem_FLRSsxxx during compilation.
The routines that support area filling with the remaining
fill styles have the same parameters as the solid fill
shape routine.
These routines use attrs->fill_raster and attrs->fill_origin
as fill raster and fill origin,
thus implementing the fill styles described in
the
.UI "Shapes Internals Manual" .
These routines must support fill rasters of the same
pixel depth as the device and also 1 bit deep fill rasters;
no other pixel depths need be supported.
The fill raster may be either a memory raster or another screen raster.
.P
Examples of these other fill routines can be found in
the following files:
.sp 1v
dd/mem/memTxS.c
.in +3P
.P
The routine is TEXTURE_SHAPE(sh_mem_TXRSs),
which eventually calls the routines in the
mxTxR.c routine corresponding to the
destination pixel depth.
.in -3P
.P
dd/mem/memOsS.c
.P
.in +3P
The routine is OPAQUE_STIPPLE_SHAPE
(sh_mem_OSRSs),
which eventually calls the routines in the
mxOsR.c routine corresponding
to the destination pixel depth.
.in -3P
.P
dd/mem/memStS.c
.P
.in +3P
The routine is STIPPLE_SHAPE (sh_mem_STRSs),
which eventually calls the routines in the
mxStR.c routine corresponding to the
destination pixel depth.
.in -3P
.H 2 "Fill Styles"
.P
\f3CTX_FILL_SOLID\fP
.P
1- or 4-bit rasters are filled with the context's current color,
CTX_COLOR.
CTX_FILL_SOLID ignores CTX_PLANE_ENABLE in the 1-bit case.
.P
\f3CTX_FILL_STIPPLED\fP
.P
Stippling works only for 1-bit source rasters.
Each pixel in the fill raster is examined.
If the source pixel is a 1,
the corresponding pixel in the destination raster is
set to the current color.
If the source pixel is not set,
the corresponding pixel in the destination is unchanged.
Only those planes enabled by CTX_PLANE_ENABLE are modified
in the destination raster.
The destination raster is the CTX_RASTER attribute of
the current context.
.br
.TB "Stippling Action"
.TS
box tab(/);
cf4I | cf4I
c | l.
Source Pixel/Action
=
1/CTX_COLOR to destination raster
_
0/Destination is unchanged
.TE
.TT
Dependent on:

CTX_FILL_RASTER
.br
CTX_PLANE_ENABLE
.P
Ignores:

RAS_PLANE_ENABLE
.P
\f3CTX_FILL_OPAQUE_STIPPLED\fP
.P
Enabled pixels are set to the current color.
Unenabled pixels are set to the background color.
Each pixel in the fill raster is examined.
If the source depth is four and the source pixel is 1,
the corresponding pixel in the destination raster is
set to the current color;
otherwise, it is set to the current background color.
.TB "Opaque Stipple Action"
.TS
box tab(/);
cf4I | cf4I | cf4I
c | c | lw(2.5i).
Source Depth/Source Pixel/Action
=
1/1/T{
CTX_COLOR to destination raster
T}
_
1/0/T{
CTX_BACK_COLOR to destination raster
T}
_
>1/non-zero/T{
CTX_COLOR to destination if the source is non-zero.
However, source raster's pixels are first ANDed with
the RAS_PLANE_ENABLE field.
T}
_
>1/0/T{
CTX_BACK_COLOR to destination
T}
.TE
.TT
Dependent on:
.DS
CTX_FILL_RASTER
.br
CTX_PLANE_ENABLE
.br
RAS_PLANE_ENABLE
.P
\f3CTX_FILL_TEXTURED\fP
.DE
Source pattern and color are replicated in the destination raster.
X11 calls this a \f2tiling\fP operation.
When invoked via a Display_Context call,
it differs from a raster copy via Display_Raster in
that it wraps the source raster in the destination raster.
.P
In 1:1 and 1:4 bit copies, however,
the following holds:
.br
.TB "Texture Fill Action"
.TS
box tab(/);
c| c| c s
c| c| c s
c| c| c| l
c| c| c| l
c| c| c| l
c| c| c s.
src/dst/Action
=
1/1/copy per pixel
_
1/>1/1/color
\^/\^/_/_
\^/\^/0/Back color
_
>1/>1/copy per pixel
.TE
.TT

Dependent on:
.DS
CTX_FILL_RASTER
.br
CTX_PLANE_ENABLE
.br
.DE
Ignores:
.DS
RAS_PLANE_ENABLE
.DE
.\" begin new page
.H 2 "Raster Copying"
.P
An example of raster copying can be found in dd/mem/memCpS.c:
.PC
/* sh_mem_CPRSs */
COPY_SHAPE(dst_raster, attrs, shape, src_raster, offset)
        RASTER      dst_raster;     /* destination raster */
        FBATTR      *attrs;         /* rendering attributes */
        SHAPE       shape;          /* destination raster clip shape */
        RASTER      src_raster;     /* source raster */
        POINT_B2D   *offset;        /* offset of source raster within
                                    destination raster */
.SF
This routine copies the source raster into the destination
raster with the requested offset using attrs->rop and
attrs->plane_enable.
The source raster must be either of the same pixel depth
as the destination raster or 1 bit deep.
If the source raster is 1 bit deep,
1 bits are expanded to attrs->col,
and 0 bits are expanded to attrs->bcol before
rendering into the destination raster.
The destination raster clip shape is guaranteed not
to reference an area outside of either the source or
destination raster.
This routine must be able to copy source rasters that
overlap destination rasters
(by supporting copies in any direction).
The source raster may be either a memory raster or another
screen raster.
.H 2 "PolyGlyph Rendering"
.P
An example of polyglyph rendering code can be found in
dd/mem8/m8FlGlS.ace:
.PC
/* sh_mem8_FLGLs */
sh_mem8_FLGLs___(ras, attrs, ref, nref, org, dim, opt, interclip)
     RASTER    ras;        /* destination raster */
     FBATTR    *attrs;     /* rendering attributes */
     GLYPH_REF *ref;       /* list of glyph refs (polyglyph) */
     Unsgn32   nref;       /* number of glyphs in polyglyph */
     POINT_B2D *org;       /* origin of polyglyph bounding box in
                              screen coordinates */
     POINT_B2D *dim;       /* dimension of polyglyph bounding box
                              in screen coordinates */
     Sgn32      opt;       /* optimization clues */
     SHAPE      interclip; /* destination clip shape, may or may
                              not be pre-intersected with
                              bounding box */
.SF
Glyphs are rendered into the destination raster as if
the glyph represents an additional 2D clip shape in
excess of the destination raster clip shape.
Only the bits that correspond to 1's in the glyph
get rendered;
the 0 bits are skipped.
This routine renders the polyglyph into the destination
raster using attrs->col, attrs->rop, and attrs->plane_enable.
It is guaranteed that no part of any glyph will lie
outside of the bounding box.
The only optimization clue currently supported at this
level is GLYPH_OPT_ABSOLUTE,
which controls whether glyphs are rendered
relative to the raster origin or absolutely
offset from the beginning of the raster.
Most polyglyphs are rendered relative to the raster origin.
Solid polyglyph rendering is all that must be
directly supported;
the other fill styles can use this and raster rendering
routines to implement their glyph rendering support.
Examples of this can be found in dd/mem/memTxGlS.c and
dd/mem/memStGlS.c
.P
Glyphs are representations of text character bit maps.
Strings of glyphs (Poly_Glyphs) are constructed using
arrays of GLYPH_REF structures.
Shapes assumes that glyphs are always allocated on aligned,
32-bit address boundaries,
and that the bit map data for a GLYPH immediately
follows the GLYPH structure in memory.
.PC
typedef struct sh_glyph
  {
   Unsgn8     gl_TYPE;       /* glyph depth and alignment */
   Unsgn8     gl_empty;      /* empty for now */
   Unsgn16    gl_WIDTH;      /* glyph width */
   Unsgn16    gl_HEIGHT;     /* glyph height */
   Unsgn16    gl_LINEBYTES;  /* struct size must be multiple of 4 bytes */
  } *GLYPH;
.SF
\f3gl_TYPE\f1
.P
The gl_TYPE field of the glyph structure is broken up
as follows  :
.PC
        8 7 6 5 4 3 2 1
        --- ----- -----
        |    |     |______ depth (1,8,4,32)
        |    |____________ alignment (8, 16, 32)
        |_________________ space/speed
.SF
Currently, Shapes only supports 1-bit depth and 16-
and 32-bit alignment.
It expects all glyphs up to 16 bits wide to be
16-bit aligned,
and anything over that to be 32-bit aligned except
for VGA.
VGA internally stores
everything 32-bit aligned.
Anything not 32-bit aligned will be converted.

.P
\f3gl_WIDTH\f1
.P
The glyph width in pixels.
.P
\f3gl_HEIGHT\f1
.P
The glyph height in pixels.
.P
\f3gl_LINEBYTES\f1
.P
The number of bytes per scanline needed to access the
glyph (including padding).
.P
The representation of glyph bit map data is
device-dependent and usually matches the bit/byte
order of the most commonly used frame buffer.
For example, the most significant bit of the first 32
bit word of data after the GLYPH is the first pixel
in the glyph Sun3 and Sun4 architectures,
while the least significant bit of that word is
the first pixel in the glyph on a Sun386 architecture.
.PC
typedef	struct
  {
   GLYPH	gr_glyph;	/* glyph to display */
   Unsgn16	gr_x, gr_y;	/* position of glyph upper left corner */
  } GLYPH_REF;
.\" begin new page
.SF
\f3gr_glyph\f1
.P
Points to the GLYPH to be displayed.
.P
\f3gr_x and gr_y\f1
.P
The raster coordinates of where the upper left corner
of that glyph should be displayed.
.P
Glyphs are rendered in Shapes as if the glyph bitmap
data represented a 2D clip mask that is being filled:\ \&
the 1's get filled and the 0's don't.
To render the background pixels,
Shapes supports X11 image text functionality,
where the polyglyph bounding box can be filled
with the background color before glyphs are
rendered over it.
.H 2 "Other Files"
.P
xxxRas.c for your device needs to support the device
specific operators for that device.
An example is dd/cg4Ras.c.
It contains the following routines:
.PC
SCREEN
sh_init_xxx(scr, ofs)
FAST	SCREEN	scr;		
.SF
This routine defines and creates an instance of the
device class for your device,
initializes the screen object for the device,
gets the device mapped into memory,
and initializes the device for use.
It returns the initialized screen object.
.PC
SCREEN
sh_xxx_open(name, scr)
	char	*name;
FAST	SCREEN	scr;
.SF
This routine opens the device and does any necessary
mapping of virtual devices to physical devices.
.PC
static
install_cmap(cmap)
FAST    CMAP  cmap;
.SF
This routine provides any necessary device-specific
hardware color map installation code necessary for your device.
Also, if your device has a device-specific cursor implementation,
the following routines also need to be supported in xxxRas.c
.PC
static
install_cursor(curs)
FAST    CURSER   curs;
.SF
This routine installs the cursor on a raster on your device.
It allocates and initializes any necessary backing raster store,
and generally prepares the raster for cursor support.
.PC
static
.br
remove_cursor(curs)
FAST    CURSER   curs;
.SF
This routine removes the cursor from the screen.
.PC
static
display_cursor(curs)
FAST	CURSER	curs;
.SF
This routine updates the cursor to a new position on the screen
(which may be the same as the previous position).
It first calls remove_cursor to remove the cursor from
the previous position.
In addition, if your device supports a new pixel depth,
you will have to also include the following routines in xxxRas.c.
The use of the APPLY_CMAP macro for a specific pixel depth
is the only thing that makes these routines device-dependent.
Examples can be found in dd/cg2/cg2Ras.c.
.PC
static void
color_ras(ras, col)
FAST	RASTER	ras;
FAST	COLOR	*col;
.SF
Updates the current foreground color and prepares the
hardware to use it.
.PC
static void
clear_ras(ras, ctx)
FAST	RASTER	ras;
FAST	CONTEXT ctx;
.SF
Clears the raster to CTX_BACK_COLOR using CTX_PLANE_ENABLE.
.PC
static void
display_ras(ras, ctx, path)
FAST	RASTER ras;
FAST	CONTEXT ctx;
	PATH	path;
.SF
Sets up the device-dependent rendering attributes
for Display_Raster.
.PC
static void
dispatch_ras(ras, attrs, func)
	RASTER 	ras;
FAST	FBATTR	*attrs;
	Unsgn8	func;     /* which function to set up */
.SF
This supports a device-independent call to set up dispatch
vectors for a particular device.
.PC
static void
write_ras(ras, data, type)
FAST    RASTER  ras;              /* RASTER object */
FAST    unsigned char *data;      /* -> data area */
FAST    RAS_data_type type;
.SF
Sets up the device-dependent rendering attributes
for Write_Raster.
.P
You will also have to add support for your device to
the generic Read_Raster function in /di/raster.c\|.
.PC
void
sh_fb_Read_Raster(ras, data, type)
FAST	RASTER  ras;            /* RASTER object */
FAST    unsigned char *data;    /* -> data area */
FAST	RAS_data_type type;
.SF
This routine reads raster data from a raster into the
user-defined data area.
Since Shapes dispatches based on the destination raster
(and in this case the destination is not under Shapes
control and probably isn't even a raster),
device-specific versions of this routine are not supported
except to assume that the destination looks like memory.
This is why there is only one generic version of this
routine that must be modified to support a device of
new pixel depth or memory architecture.
.PC
static void
store_ras(ras, ctx)
FAST	RASTER	ras;
FAST	CONTEXT	ctx;
.SF
Sets up the device-dependent rendering attributes
for Store_Raster.
.PC
static void
glyph_ras(ras, ctx, gr, n, org, dim, opt)
FAST	RASTER	ras;
FAST	CONTEXT	ctx;        /* context to display in */
	GLYPH_REF *gr;      /* glyph reference list */
	Unsgn16	n;          /* number of glyph references */
FAST	POINT_B2D *org;     /* upper left corner of bounding box */
FAST	POINT_B2D *dim;     /* pixel dimensions of bounding box */
	Unsgn32	opt;        /* optimization flags */
.SF
Sets up the device-dependent rendering attributes for Poly_Glyph.
This routine also supports the GLYPH_OPT_CLEAR attribute,
which clears the polyglyph bounding box to CTX_BACK_COLOR
before rendering the polyglyph.
.P
In addition, if you add a device with a new pixel depth,
you will probably have to provide new color map routine
replacements for most of the existing routines.
Examples can be found in /dd/m8Cmap.c.
They include:
.PC
static
apply_cmap_ind_8(cmap, col)
	CMAP	cmap;
FAST	COLOR	*col;
.SF
This routine translates a Shapes indexed COLOR into
a pixel value that can be used on the device to produce that COLOR.
There is also a macro defined for this function that
is used instead in all device-specific references to APPLY_CMAP.
This routine is not used for VGA.
.PC
static
apply_cmap_dir_8(cmap, col)	/* 8 bit FB, direct color */
	CMAP	cmap;
FAST	COLOR	*col;
.SF
This routine translates a Shapes direct COLOR into a
pixel value that can be used on the device to produce that COLOR.
There is also a macro defined for this function that
is used instead in all device-specific references to APPLY_CMAP.
This routine is not used for VGA.
.PC
static COLOR *
col_dir_8(cmap, index)
	CMAP	cmap;
FAST	COLOR	*index;
.SF
This routine maps RGB color values into indexed color
values using a predetermined,
fixed color cube for devices such as 8-bit frame buffers
that cannot directly support RGB colors.
.PC
static CMAP
init_cmap8(cmap)
FAST	CMAP	cmap;
.SF
This function handles default initialization of a color map object.
It is called for each newly-created color map object.
.PC
static
install_cmap8(cmap)
FAST	CMAP	cmap;
.SF
This routine populates the memory color map by calling
the color function.
Each device has a corresponding routine that
first calls this generic routine to populate the
memory color map,
then installs that color map into the hardware
color map,
if one exists.
.PC
void
sh_Set_Cmap8(cmap, attr, val)
FAST	CMAP cmap;
	CMAP_attr attr;
	int	val;
.SF
This routine provides support for setting color map attributes.
.PC
static
write_cmap8(cmap, data, format)
FAST	CMAP	cmap;
	Unsgn8	*data;
	Unsgn32	format;
.SF
This routine provides a high-performance method of directly
writing device-dependent color values into a memory color map.
It also sets the CMAP_FUNC_IGNORE flag to prevent these
values from being overwritten when install_cmap is called.
Supported formats are defined in /include/sh_CMAP.h.
.PC
static
read_cmap8(cmap, data, format)
FAST	CMAP	cmap;
	Unsgn8	*data;
	Unsgn32	format;
.SF
This routine provides a high-performance method of directly
reading device-dependent color values from a memory color map.
Supported formats are defined in /include/sh_CMAP.h.
.PC
new_depth(cmap)
FAST	CMAP	cmap;
.SF
This routine uses the color map size value to determine
the nearest power of 2 greater than or equal to that size.
The power of 2 is then assigned to the cmap_depth attribute.
