123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- \input texinfo @c -*-texinfo-*-
- @c %**start of header
- @setfilename libxmi.info
- @settitle The GNU @code{libxmi} 2-D Rasterization Library
- @c For double-sided printing, uncomment:
- @c @setchapternewpage odd
- @c %**end of header
- @dircategory Libraries
- @direntry
- * Libxmi: (libxmi). The GNU libxmi 2-D rasterization library.
- @end direntry
- @ifinfo
- This file documents version 1.3 of the GNU libxmi 2-D rasterization library.
- Copyright @copyright{} 1998--2005 Free Software Foundation, Inc.
- Permission is granted to make and distribute verbatim copies of
- this manual provided the copyright notice and this permission notice
- are preserved on all copies.
- Permission is granted to copy and distribute modified versions of this
- manual under the conditions for verbatim copying, provided that the entire
- resulting derived work is distributed under the terms of a permission
- notice identical to this one.
- Permission is granted to copy and distribute translations of this manual
- into another language, under the above conditions for modified versions,
- except that this permission notice may be stated in a translation approved
- by the Foundation.
- @end ifinfo
- @titlepage
- @title The GNU @code{libxmi} 2-D Rasterization Library
- @subtitle Version 1.3
- @author Robert S. Maier
- @page
- @vskip 0pt plus 1filll
- Copyright @copyright{} 1998--1999 Free Software Foundation, Inc.
- Permission is granted to make and distribute verbatim copies of
- this manual provided the copyright notice and this permission notice
- are preserved on all copies.
- Permission is granted to copy and distribute modified versions of this
- manual under the conditions for verbatim copying, provided that the entire
- resulting derived work is distributed under the terms of a permission
- notice identical to this one.
- Permission is granted to copy and distribute translations of this manual
- into another language, under the above conditions for modified versions,
- except that this permission notice may be stated in a translation approved
- by the Foundation.
- @end titlepage
- @page
- @node Top, libxmi Overview, (dir), (dir)
- @chapter The @code{libxmi} 2-D Rasterization Library
- This is the documentation for version 1.3 of the GNU @code{libxmi} 2-D
- rasterization library, which is used by @w{C and} C++ programmers.
- @w{It converts} 2-D geometrical objects, such as polylines, polygons,
- and arcs, to raster patterns. There is support for setting drawing
- attributes, including line width, join style, cap style, and a
- multicolored dash pattern. The objects may be unfilled or filled.
- @w{If the latter}, the filling may be a solid color, @w{a stipple}
- pattern, or a texture. There is support for sophisticated color-merging
- between separately drawn objects.
- @menu
- * libxmi Overview:: GNU libxmi and its features
- * libxmi Example:: A sample program that may be linked with libxmi
- * libxmi API:: The libxmi API
- * Acknowledgements:: The contributors
- @end menu
- @node libxmi Overview, libxmi Example, Top, Top
- @section An overview of @code{libxmi}
- With the aid of the GNU @code{libxmi} library, a C or C++ programmer may
- rasterize two-dimensional geometric objects; @w{that is}, draw them on a
- two-dimensional array of pixels. The supported objects are points,
- polylines, filled polylines (i.e., polygons), rectangles, filled
- rectangles, and `arcs': segments of ellipses whose principal axes are
- aligned with the coordinate axes. Like polylines and rectangles, arcs
- may be unfilled or filled.
- The corresponding rendering functions in the @code{libxmi} API
- (application programming interface) are @code{miDrawPoints},
- @code{miDrawLines}, @code{miFillPolygon}, @code{miDrawRectangles},
- @code{miFillRectangles}, @code{miDrawArcs}, and @code{miFillArcs}. Each
- of these takes an array, rather than a single object, as an argument.
- For example, one of the arguments of @code{miDrawLines} is an array of
- points, interpreted as the vertices of a polyline. The polygon filled
- by @code{miFillPolygon} is specified similarly. And the final four
- functions render lists of objects, rather than single objects.
- Actually, @code{libxmi} provides a two-stage graphics pipeline. In the
- first stage, an opaque object called a @code{miPaintedSet} is drawn
- onto. Each of the eight drawing functions takes a pointer to a
- @code{miPaintedSet} as its first argument. Conceptually, a
- @code{miPaintedSet} is an unordered set of points with integer
- coordinates, partitioned by pixel value. The datatype representing a
- pixel value is @code{miPixel}, which is normally typedef'd as
- @code{unsigned int}. Each of the drawing functions takes a pointer to a
- @code{miGC}, or graphics context, as its second argument. The
- @code{miGC} specifies such drawing attributes as line width, join style,
- cap style, and dashing style, and also the pixel value(s) to be used in
- the painting operation.
- In the first stage of the pipeline the Painter's Algorithm is used, so
- that a repeatedly-painted point in a @code{miPaintedSet} acquires the
- pixel value applied @w{to it} in the final drawing operation. In the
- second stage, more sophisticated pixel-merging algorithms may be
- applied. @w{In this} stage, a @code{miPaintedSet} is copied (`merged')
- onto a @code{miCanvas}, by invoking @code{miCopyPaintedSetToCanvas}.
- @w{A @code{miCanvas}} is a structure that includes a @code{miPixmap}: a
- two-dimensional array of @code{miPixel}s that may be initialized by the
- user, and read, pixel by pixel, after the merging is performed. By
- default, @code{miCopyPaintedSetToCanvas} uses the Painter's Algorithm
- too, so that the source pixel in the @code{miPaintedSet} replaces the
- destination pixel in the @code{miCanvas}. But the merging process may
- be controlled in much finer detail. @w{A stipple} bitmap and a texture
- pixmap, and binary and ternary pixel-merging functions, may be
- specified.
- The @emph{interpretation} of pixel values is left @w{up to} the user.
- @w{A @code{miPixel}} could be an index into a color table. @w{It could}
- also be an encoding of a color according to the RGB scheme, the RGBA
- scheme, or some other scheme. Even though a @code{miPixel} is normally
- an @code{unsigned int}, this may be altered, if desired, at the time
- @code{libxmi} is installed. Any scalar type or nonscalar type,
- including a structure or a union, could be substituted.
- @code{libxmi} is intended for use both as a standalone library and as a
- rendering module that may be incorporated in other packages. To
- facilitate its use in other packages, it may be extensively customized
- at installation time. Besides customizing the definition of
- @code{miPixel}, it is possible to customize the definition of the
- @code{miPixmap} datatype, which by default is an array of pointers to
- rows of @code{miPixel}s. The default merging algorithm used by
- @code{miCopyPaintedSetToCanvas} may also be altered: @w{it need} not be
- the Painter's Algorithm. For instructions on customization, see the
- comments in the @code{libxmi} header file @file{xmi.h}.
- @node libxmi Example, libxmi API, libxmi Overview, Top
- @section A sample @code{libxmi} program
- The following C program uses @code{libxmi} to create a
- @code{miPaintedSet}, draws a dashed polyline and a dashed elliptic arc
- on the @code{miPaintedSet}, and transfers the painted pixels to a
- @code{miCanvas} that includes a pixmap of specified size. Finally, it
- writes the pixmap to standard output.
- @example
- @group
- #include <stdio.h>
- #include <stdlib.h>
- #include <xmi.h> /* public libxmi header file */
- @end group
- @group
- int main ()
- @{
- miPoint points[4]; /* 3 line segments in the polyline */
- miArc arc; /* 1 arc to be drawn */
- miPixel pixels[4]; /* pixel values for drawing and dashing */
- unsigned int dashes[2]; /* length of `on' and `off' dashes */
- miGC *pGC; /* graphics context */
- miPaintedSet *paintedSet; /* opaque object to be painted */
- miCanvas *canvas; /* drawing canvas (including pixmap) */
- miPoint offset; /* for miPaintedSet -> miCanvas transfer */
- int i, j;
- @end group
-
- @group
- /* define polyline: vertices are (25,5) (5,5), (5,25), (35,22) */
- points[0].x = 25; points[0].y = 5;
- points[1].x = 5; points[1].y = 5;
- points[2].x = 5; points[2].y = 25;
- points[3].x = 35; points[3].y = 22;
- @end group
- @group
- /* define elliptic arc */
- arc.x = 20; arc.y = 15; /* upper left corner of bounding box */
- arc.width = 30; /* x range of box: 20..50 */
- arc.height = 16; /* y range of box: 15..31 */
- arc.angle1 = 0 * 64; /* starting angle (1/64'ths of a degree) */
- arc.angle2 = 270 * 64; /* angle range (1/64'ths of a degree) */
- @end group
- @group
- /* create and modify graphics context */
- pixels[0] = 1; /* pixel value for `off' dashes, if drawn */
- pixels[1] = 2; /* default pixel for drawing */
- pixels[2] = 3; /* another pixel, for multicolored dashes */
- pixels[3] = 4; /* another pixel, for multicolored dashes */
- @end group
- @group
- dashes[0] = 4; /* length of `on' dashes */
- dashes[1] = 2; /* length of `off' dashes */
- @end group
- @group
- pGC = miNewGC (4, pixels);
- miSetGCAttrib (pGC, MI_GC_LINE_STYLE, MI_LINE_ON_OFF_DASH);
- miSetGCDashes (pGC, 2, dashes, 0);
- miSetGCAttrib (pGC, MI_GC_LINE_WIDTH, 0); /* Bresenham algorithm */
- @end group
- @group
- /* create empty painted set */
- paintedSet = miNewPaintedSet ();
- @end group
- @group
- /* paint dashed polyline and dashed arc onto painted set */
- miDrawLines (paintedSet, pGC, MI_COORD_MODE_ORIGIN, 4, points);
- miDrawArcs (paintedSet, pGC, 1, &arc);
- @end group
- @group
- /* create 60x35 canvas (initPixel=0); merge painted set onto it */
- canvas = miNewCanvas (60, 35, 0);
- offset.x = 0; offset.y = 0;
- miCopyPaintedSetToCanvas (paintedSet, canvas, offset);
- @end group
- @group
- /* write canvas's pixmap (a 60x35 array of miPixels) to stdout */
- for (j = 0; j < canvas->drawable->height; j++)
- @{
- for (i = 0; i < canvas->drawable->width; i++)
- /* note: column index precedes row index */
- printf ("%d", canvas->drawable->pixmap[j][i]);
- printf ("\n");
- @}
- @end group
- @group
- /* clean up */
- miDeleteCanvas (canvas);
- miDeleteGC (pGC);
- miClearPaintedSet (paintedSet); /* not necessary */
- miDeletePaintedSet (paintedSet);
- @end group
-
- @group
- return 0;
- @}
- @end group
- @end example
- This program illustrates how @code{miPaintedSet}, @code{miGC}, and
- @code{miCanvas} objects are created and destroyed, @w{as well} as
- manipulated. Each of these types has a constructor and a destructor,
- named @code{miNew}@dots{} and @code{miDelete}@dots{}, respectively.
- When creating a @code{miGC} with @code{miNewGC}, an array of
- @code{miPixel}s of length at @w{least 2} must be passed as the second
- argument. The first argument, @code{npixels}, is the length of the
- array. The default color for drawing operations will be pixel @w{number
- 1} in the array. The other pixel colors in the array will only be used
- when dashing. @w{In normal} (on/off) dashing, the colors of the `on'
- dashes will cycle through the colors numbered 1,2,@dots{},npixels-1 in
- the array. In so-called double dashing, the `off' dashes will be drawn
- too, in color @w{number 0}.
- In the program, the first call to @code{miGCSetAttrib} sets the line
- mode to @code{MI_LINE_ON_OFF_DASH} rather than @code{MI_DOUBLE_DASH}@.
- This replaces the default, which is @code{MI_LINE_SOLID}, meaning no
- dashing (only color @w{number 1} in the pixel array is used). @w{An
- array} of dash lengths is then specified by calling
- @code{miSetGCDashes}. (The default dash length array, which is
- replaced, is @code{@{4,4@}}). When dashing, the specified dash length
- array will be cyclically used. The first dash will be `on', the second
- `off', and @w{so forth}. The third argument to @code{miSetGCDashes}
- specifies an initial offset into this cyclic pattern. Currently, the
- offset must be nonnegative.
- The second call to @code{miGCSetAttrib} sets the line width in the
- graphics context. @w{If the} specified line width is positive, lines
- and arcs will be drawn with a circular brush whose diameter is equal to
- the line width. All pixels within the brushed region will be painted.
- @w{If the} line width is zero, as it is here, a so-called Bresenham
- algorithm will be used. Bresenham lines and arcs are drawn with fewer
- pixels than is the case for lines and arcs with @w{width 1}, and many
- people prefer them.
- @code{miDrawLines} and @code{miDrawArc} do the actual drawing. They are
- passed a polyline (i.e., an array of @code{miPoint}s) and a
- @code{miArc}, respectively. The definitions of the @code{miPoint} and
- @code{miArc} structures appear in the header file @file{xmi.h}, which is
- worth examining. The third argument of @code{miDrawLines},
- @code{MI_COORD_MODE_ORIGIN}, specifies that the points of the polyline,
- after the first, are expressed in absolute rather than relative
- coordinates.
- Finally, the program transfers the painted pixels to a @code{miCanvas},
- and copies the pixels from it to standard output. @w{A
- @code{miCanvas}}, unlike a @code{miPaintedSet} and a @code{miGC}, is not
- an opaque object, so its elements may be read (and written). @w{In
- fact}, a @code{miCanvas} may be constructed by hand and passed to the
- @code{miCopyPaintedSetToCanvas} function. However, it is usually
- easiest to use the constructor @code{miNewCanvas} and the destructor
- @code{miDeleteCanvas}. Any @code{miCanvas} created with
- @code{miNewCanvas} is allocated on the heap, with @code{malloc}. @w{It
- includes} a pixmap (@w{an array} of @code{miPixel}s, of specified size)
- that is itself allocated on the heap.
- It is only when the painted pixels are transferred from
- @code{miPaintedSet} to @code{miCanvas} that clipping to a pixmap takes
- place. Drawing to a @code{miPaintedSet} is entirely unclipped: @w{at
- least} in principle, the @code{miPaintedSet} is of potentially infinite
- extent. However, the pixmap in the @code{miCanvas} created by
- @code{miNewCanvas (60, 35, 0)} has upper left corner @code{(0,0)} and
- lower right corner @code{(59,34)}. Out-of-bound painted pixels, @w{if
- any}, will not be transferred.
- The third argument of @code{miNewCanvas} is its @code{initPixel}
- argument: the pixel value @w{to which} each @code{miPixel} in the pixmap
- is initialized. Since this value @w{is `0'}, the pixmap that is sent to
- standard output will display the dashed polyline and arc in the `2',
- `3', @w{and `4'} colors, on a background of zeroes.
- @node libxmi API, Acknowledgements, libxmi Example, Top
- @section The @code{libxmi} API
- @menu
- * Opaque Data Structures:: The miPaintedSet and miGC structures
- * First Stage:: Painting pixels in a miPaintedSet
- * Second Stage:: Merging a miPaintedSet onto a miCanvas
- @end menu
- @node Opaque Data Structures, First Stage, libxmi API, libxmi API
- @subsection Opaque data structures
- The drawing functions used in the first stage of the @code{libxmi}
- graphics pipeline paint pixels on a @code{miPaintedSet}.
- A @code{miPaintedSet} should be thought of as an unordered set of points
- with integer coordinates, partitioned according to pixel value. Any
- pixel value is a @code{miPixel}, which in most @code{libxmi}
- installations is typedef'd as an @code{unsigned int}.
- A @code{miPaintedSet} is an opaque object that must be accessed through
- a pointer. The functions
- @example
- @group
- miPaintedSet * miNewPaintedSet (void);
- void miDeletePaintedSet (miPaintedSet *paintedSet);
- @end group
- @end example
- @noindent
- are the constructor and destructor for the @code{miPaintedSet} type.
- The function
- @example
- void miClearPaintedSet (miPaintedSet *paintedSet);
- @end example
- @noindent
- clears all pixels from a @code{miPaintedSet}, i.e., makes it the empty
- set.
- All drawing functions that paint pixels on a @code{miPaintedSet} take a
- pointer to a graphics context as an argument. @w{A graphics} context is
- an opaque object, called a @code{miGC}, that contains drawing
- parameters. The functions
- @example
- @group
- miGC * miNewGC (int npixels, const miPixel *pixels);
- void miDeleteGC (miGC *pGC);
- miGC * miCopyGC (const miGC *pGC);
- @end group
- @end example
- @noindent
- are the constructor, destructor, and copy constructor for the
- @code{miGC} type. The arguments of @code{miNewGC} specify an array of
- @code{miPixel}s, which must have length at @w{least 2}. The default
- color for drawing operations will be pixel @w{number 1} in the array.
- The other pixel colors in the array will only be used when dashing.
- @w{In normal} (on/off) dashing, the colors of the `on' dashes will cycle
- through the colors numbered 1,2,@dots{},npixels-1. In so-called double
- dashing, the `off' dashes will be drawn too, in color @w{number 0}.
- The array of pixel colors may be modified at any later time, by invoking
- the function @code{miSetGCPixels}.
- @example
- void miSetGCPixels (miGC *pGC, int npixels, const miPixel *pixels);
- @end example
- @noindent
- is the declaration of this function.
- The lengths of dashes, when dashing, may be set by invoking
- @code{miSetGCDashes}. It has declaration
- @example
- void miSetGCDashes (miGC *pGC, int ndashes, const unsigned int *dashes,
- int offset);
- @end example
- @noindent
- Here @code{dashes} is an array of length @code{ndashes}. The array is
- cyclically used. The first dash in a polyline or arc will be an `on'
- dash of length @code{dashes[0]}; the next dash will be an `off' dash of
- length @code{dashes[1]}; and so forth. The default dash length array in
- any @code{miGC} is @code{@{4,4@}}. The dash length array need not have
- the same length as the pixel color array, and it need not have even
- length. @code{offset}, if nonzero, is an initial offset into the dash
- pattern. For example, if it equals @code{dashes[0]} then the first dash
- will be an `off' dash of length @code{dashes[1]}. Currently,
- @code{offset} must be nonnegative.
- Besides the array of pixel colors and the array of dash lengths, any
- @code{miGC} contains several attributes whose values are @code{enum}s,
- and an integer-valued line width attribute. Any one of these may be set
- by invoking @code{miSetGCAttrib}, and any list of them by invoking
- @code{miSetGCAttribs}. The declarations of these functions are:
- @example
- typedef enum @{ MI_GC_FILL_RULE, MI_GC_JOIN_STYLE, MI_GC_CAP_STYLE,
- MI_GC_LINE_STYLE, MI_GC_ARC_MODE, MI_GC_LINE_WIDTH
- @} miGCAttribute;
- @group
- void miSetGCAttrib (miGC *pGC, miGCAttribute attribute, int value);
- void miSetGCAttribs (miGC *pGC, int nattributes,
- const miGCAttribute *attributes,
- const int *values);
- @end group
- @end example
- @noindent
- These attributes are similar to the drawing attributes used in the @w{X
- Window} System. The allowed values for the attribute
- @code{MI_GC_FILL_RULE}, which specifies the rule used when filling
- polygons and arcs, are:
- @example
- enum @{ MI_EVEN_ODD_RULE, MI_WINDING_RULE @};
- @end example
- @noindent
- The default is @code{MI_EVEN_ODD_RULE}@. The allowed values for the
- attribute @code{MI_GC_JOIN_STYLE}, which specifies the rule used when
- joining polylines and polyarcs, are:
- @example
- enum @{ MI_JOIN_MITER, MI_JOIN_ROUND, MI_JOIN_BEVEL,
- MI_JOIN_TRIANGULAR @};
- @end example
- @noindent
- The default is @code{MI_JOIN_MITER}@. The allowed values for the
- attribute @code{MI_GC_CAP_STYLE}, which specifies the rule used when
- capping the ends of polylines and arcs, are:
- @example
- enum @{ MI_CAP_NOT_LAST, MI_CAP_BUTT, MI_CAP_ROUND, MI_CAP_PROJECTING,
- MI_CAP_TRIANGULAR @};
- @end example
- @noindent
- The default is @code{MI_CAP_BUTT}@. The allowed values for the
- attribute @code{MI_GC_LINE_STYLE}, which specifies whether or not
- dashing should take place when drawing polylines and arcs, are:
- @example
- enum @{ MI_LINE_SOLID, MI_LINE_ON_OFF_DASH, MI_LINE_DOUBLE_DASH @};
- @end example
- @noindent
- The default is @code{MI_LINE_SOLID}@. The allowed values for the
- attribute @code{MI_GC_ARC_MODE}, which specifies how arcs should be
- filled, are:
- @example
- enum @{ MI_ARC_CHORD, MI_ARC_PIE_SLICE @};
- @end example
- @noindent
- The default is @code{MI_ARC_PIE_SLICE}@.
- Finally, the value for the line width, i.e., for the
- @code{MI_GC_LINE_WIDTH} attribute, may be any nonnegative integer. The
- default @w{is 0}, which has a special meaning. Zero-width lines and
- arcs are not invisible. Instead, they are drawn with a Bresenham
- algorithm, which paints fewer pixels than is the case for lines with
- @w{width 1}.
- Any @code{miGC} also contains a miter-limit attribute, which, if the
- join mode attribute has value @code{MI_JOIN_MITER} and the line width is
- at @w{least 1}, will affect the drawing of the joins in polylines and
- polyarcs. @w{At any} join point, the `miter length' is the distance
- between the inner corner and the outer corner. The miter limit is the
- maximum value that can be tolerated for the miter length divided by the
- line width. @w{If this} value is exceeded, the miter will be `@w{cut
- off}': the @code{MI_JOIN_BEVEL} join mode will be used instead.
- The function
- @example
- void miSetGCMiterLimit (miGC *pGC, double miter_limit);
- @end example
- @noindent
- sets the value of this attribute. The specified value must be greater
- than or equal @w{to 1.0}. That is because the miter limit is the
- cosecant of one-half of the minimum join angle for mitering, so values
- less @w{than 1.0} are meaningless. The default value for the miter
- limit is 10.43, as in the @w{X Window} System. @w{10.43 is} the
- cosecant of 5.5 degrees, so by default, miters will be @w{cut off} if
- the join angle is less than @w{11 degrees}.
- @node First Stage, Second Stage, Opaque Data Structures, libxmi API
- @subsection The first stage of the graphics pipeline
- In the first stage of the @code{libxmi} graphics pipeline, one or more
- of the core drawing functions is invoked. Each drawing function takes
- pointers to a @code{miPaintedSet} and a @code{miGC} (@w{a graphics}
- context) as its first and second arguments. @w{It will} paint pixels in
- the @code{miPaintedSet}, according to the drawing parameters in the
- graphics context.
- The drawing functions fall into three groups: (1) functions that draw
- points, polylines, and polygons, @w{(2) functions} that draw rectangles,
- and @w{(3) functions} that draw `arcs' (segments of ellipses whose
- principal axes are aligned with the coordinate axes). @w{We discuss}
- these three groups @w{in turn}.
- The point/polyline/polygon group includes:
- @example
- void miDrawPoints (miPaintedSet *paintedSet, const miGC *pGC,
- miCoordMode mode, int npts, const miPoint *pPts);
- void miDrawLines (miPaintedSet *paintedSet, const miGC *pGC,
- miCoordMode mode, int npts, const miPoint *pPts);
- void miFillPolygon (miPaintedSet *paintedSet, const miGC *pGC,
- miPolygonShape shape,
- miCoordMode mode, int npts, const miPoint *pPts);
- @end example
- @noindent
- The final three arguments of each are a coordinate mode, a specified
- number of points, and an array that contains that number of points.
- @code{miDrawPoints} draws the array as a cloud of points,
- @code{miDrawLines} draws a polyline defined by the array, and
- @code{miFillPolygon} fills a polygon defined by the array. The
- @code{mode} argument specifies whether the points in the array, after
- the first, are in absolute or relative coordinates. Its possible values
- are:
- @example
- typedef enum @{ MI_COORD_MODE_ORIGIN,
- MI_COORD_MODE_PREVIOUS @} miCoordMode;
- @end example
- @noindent
- The @code{miPoint} structure is defined by
- @example
- typedef struct
- @{
- int x, y; /* integer coordinates, y goes downward */
- @} miPoint;
- @end example
- @noindent
- The additional @code{shape} argument of @code{miFillPolygon} is
- advisory. Its possible values are:
- @example
- typedef enum @{ MI_SHAPE_GENERAL, MI_SHAPE_CONVEX @} miPolygonShape;
- @end example
- @noindent
- They indicate whether the polygon is (1) unconstrained (i.e., not
- necessarily convex, with self-intersections allowed), or @w{(2) convex}
- and not self-intersecting. The latter case can be drawn more rapidly.
- The rectangle group includes
- @example
- void miDrawRectangles (miPaintedSet *paintedSet, const miGC *pGC,
- int nrects, const miRectangle *pRects);
- void miFillRectangles (miPaintedSet *paintedSet, const miGC *pGC,
- int nrects, const miRectangle *pRects);
- @end example
- @noindent
- The final two arguments of each are a specified number of rectangles and
- an array that contains that number of rectangles.
- @code{miDrawRectangles} draws the outline of each rectangle, and
- @code{miFillRectangle} fills each rectangle. The @code{miRectangle}
- structure is defined by
- @example
- typedef struct
- @{
- int x, y; /* upper left corner of rectangle */
- unsigned int width, height; /* dimensions: width>=1, height>=1 */
- @} miRectangle;
- @end example
- @noindent
- The rectangle group is redundant, since a rectangle is a special sort of
- polyline, defined by a five-point point array in which the last point is
- the same as the first.
- The arc group includes
- @example
- void miDrawArcs (miPaintedSet *paintedSet, const miGC *pGC,
- int narcs, const miArc *parcs);
- void miFillArcs (miPaintedSet *paintedSet, const miGC *pGC,
- int narcs, const miArc *parcs);
- @end example
- @noindent
- The final two arguments of each are a specified number of arcs and an
- array that contains that number of arcs. @code{miDrawArcs} draws each
- arc. @w{It will} join successive arcs, if they are contiguous,
- according to the `join mode' in the graphics context. Similarly,
- @code{miFillArcs} will fill each arc according to the `arc mode' in the
- graphics context. Either a pie slice or a chord will be filled.
- The @code{miArc} structure is defined by
- @example
- typedef struct
- @{
- int x, y; /* upper left corner of ellipse's bounding box */
- unsigned int width, height; /* dimensions: width>=1, height>=1 */
- int angle1, angle2; /* initial angle, angle range (in 1/64 degrees) */
- @} miArc;
- @end example
- @noindent
- @code{x}, @code{y}, @code{width}, @code{height} specify a rectangle
- aligned with the coordinate axes, and @code{angle1}, @code{angle2}
- specify an angular range (a `pie slice') of an ellipse inscribed in the
- rectangle. By convention, they are the starting polar angle and angle
- range of the circular arc that would be produced from the elliptic arc
- by squeezing the rectangle into a square.
- @code{miDrawArcs} maintains a cache of rasterized ellipses. This cache
- is persistent, and internal to @code{libxmi}; accordingly,
- @code{miDrawArcs} is not reentrant. For applications in which
- reentrancy is important, a reentrant counterpart is provided. @w{It is}
- @example
- void miDrawArcs_r (miPaintedSet *paintedSet, const miGC *pGC,
- int narcs, const miArc *parcs,
- miEllipseCache *ellipseCache);
- @end example
- @noindent
- The caller of @code{miDrawArcs_r} must supply a pointer to a
- @code{miEllipseCache} object as the final argument. @w{A pointer} to
- such an object, which is opaque, is returned by
- @code{miNewEllipseCache}. After zero or more calls to
- @code{miDrawArcs_r}, the object would be deleted by a call to
- @code{miDeleteEllipseCache}. The declarations
- @example
- @group
- miEllipseCache * miNewEllipseCache (void);
- void miDeleteEllipseCache (miEllipseCache *ellipseCache);
- @end group
- @end example
- @noindent
- are supplied in the header file @file{xmi.h}.
- @node Second Stage, , First Stage, libxmi API
- @subsection The second stage of the graphics pipeline
- In the second state of the graphics pipeline, the pixels in a
- @code{miPaintedSet} are transferred (`merged') to a @code{miCanvas}, by
- invoking @code{miCopyPaintedSetToCanvas}. @w{It is} only when the
- painted pixels are transferred to a @code{miCanvas} that clipping to a
- pixmap takes place.
- @w{A @code{miCanvas}} is a structure that includes a pixmap and several
- parameters that control the transfer of pixels. Since it is not opaque,
- it may be constructed and modified @w{by hand}, if necessary. The
- @code{miCanvas} type has definition
- @example
- typedef struct
- @{
- miCanvasPixmap *drawable; /* the pixmap */
- @group
- miBitmap *stipple; /* a mask, if non-NULL */
- miPoint stippleOrigin; /* placement of upper left corner */
- @end group
- @group
- miPixmap *texture; /* a texture, if non-NULL */
- miPoint textureOrigin; /* placement of upper left corner */
- @end group
- @group
- miPixelMerge2 pixelMerge2; /* binary merging function, if non-NULL */
- miPixelMerge3 pixelMerge3; /* ternary counterpart, if non-NULL */
- @end group
- @} miCanvas;
- @end example
- @noindent
- Here, the @code{miBitmap} and @code{miPixmap} types are defined by
- @example
- typedef struct
- @{
- int **bitmap; /* each element is 0 or 1 */
- unsigned int width;
- unsigned int height;
- @}
- miBitmap;
- @end example
- @example
- typedef struct
- @{
- miPixel **pixmap; /* each element is a miPixel */
- unsigned int width;
- unsigned int height;
- @}
- miPixmap;
- @end example
- @noindent
- That is, each of them contains an array of pointers to rows (@w{of
- integers} or pixel values, as the case @w{may be}). @w{In most}
- installations of @code{libxmi}, @code{miCanvasPixmap} is typedef'd as
- @code{miPixmap}. The typedefs
- @example
- @group
- typedef miPixel (*miPixelMerge2) (miPixel source, miPixel destination);
- typedef miPixel (*miPixelMerge3) (miPixel texture, miPixel source,
- miPixel destination);
- @end group
- @end example
- @noindent
- define the datatypes of the binary and ternary pixel-merging function
- members.
- The functions
- @example
- @group
- miCanvas * miNewCanvas (unsigned int width, unsigned int height,
- miPixel initPixel);
- void miDeleteCanvas (miCanvas *pCanvas);
- miCanvas * miCopyCanvas (const miCanvas *pCanvas);
- @end group
- @end example
- @noindent
- are the constructor, destructor, and copy constructor for the
- @code{miCanvas} type. Rather than a @code{miCanvas} being created @w{by
- hand}, @code{miNewCanvas} is usually used instead. The @code{initPixel}
- argument is a @code{miPixel} value with which the newly allocated pixmap
- should be filled. The @code{stipple} and @code{texture} pointers in a
- newly created @code{miCanvas} are @code{NULL}, as are the pixel-merging
- function members. The four convenience functions
- @example
- @group
- void miSetCanvasStipple (miCanvas *pCanvas, const miBitmap *pStipple,
- miPoint stippleOrigin);
- void miSetCanvasTexture (miCanvas *pCanvas, const miPixmap *pTexture,
- miPoint textureOrigin);
- @end group
- @group
- void miSetPixelMerge2 (miCanvas *pCanvas, miPixelMerge2 pixelMerge2);
- void miSetPixelMerge3 (miCanvas *pCanvas, miPixelMerge3 pixelMerge3);
- @end group
- @end example
- @noindent
- may be used to set these members.
- The @code{miCopyPaintedSetToCanvas} function, which implements the
- second stage of the graphics pipeline, can now be discussed. @w{It has}
- declaration
- @example
- void miCopyPaintedSetToCanvas (const miPaintedSet *paintedSet,
- miCanvas *canvas, miPoint origin);
- @end example
- @noindent
- where @code{origin} is the point on the @code{miCanvas} to which the
- point @code{(0,0)} in the @code{miPaintedSet} is mapped. (@w{It could}
- equally well be called @code{offset}.)
- The semantics of @code{miCopyPaintedSet} boil down to a single issue:
- how a `source' pixel in a @code{miPaintedSet} is merged onto the
- corresponding `destination' pixel in a @code{miCanvas} to form a new
- pixel. The simplest case is when no texture is specified (the
- corresponding pointer in the @code{miCanvas} is @code{NULL})@. @w{In
- that} case, if the binary pixel-merging function member of the
- @code{miCanvas} is @code{NULL}, a default merging algorithm will be
- used. @w{In most} @code{libxmi} installations this is the Painter's
- Algorithm: the new pixel in the @code{miCanvas} will simply be the
- source pixel. @w{If, on} the other hand, the binary pixel-merging
- function in the @code{miCanvas} is non-@code{NULL}, @w{it will} be used
- to compute the new pixel.
- A texture pixmap may be specified. If so, it will be extended
- periodically so as to cover the @code{miCanvas}, and its value at the
- location of the destination pixel will affect the merging process.
- @w{If the} ternary pixel-merging function member of the @code{miCanvas}
- is @code{NULL}, a default merging algorithm, appropriate to the case
- when a texture is present, will be used. @w{In most} @code{libxmi}
- installations this is a variant of the Painter's Algorithm: the new
- pixel in the @code{miCanvas} will be the texture pixel, rather than the
- source pixel. @w{If, on} the other hand, the ternary pixel-merging
- function in the @code{miCanvas} is non-@code{NULL}, @w{it will} be used
- to compute the new pixel.
- Any @code{miCanvas} may also include a pointer to a stipple bitmap.
- @w{If so}, it will be extended periodically so as to cover the
- @code{miCanvas}, and its value at the location of the destination pixel
- will determine whether or not its replacement by a new pixel, according
- to one of the preceding rules, will take place. @w{If the} stipple
- value is zero, @w{it will} not; otherwise it will. Stipple bitmaps are
- useful for creating so-called screen door patterns, and more generally
- for protecting, or @w{masking off}, part of a @code{miCanvas}.
- @node Acknowledgements, , libxmi API, Top
- @unnumbered Acknowledgements
- @code{libxmi} is based on the machine-independent 2-D graphics routines
- in the X11 sample server code. Those routines fill polygons and draw
- wide polygonal lines and arcs. They were written by Brian Kelleher,
- Joel McCormack, Todd Newman, Keith Packard, Robert Scheifler and Ken
- Whaley, who worked for Digital Equipment Corp., MIT, and/or the @w{X
- Consortium}, and are copyright @copyright{} 1985--89 by the @w{X
- Consortium}.
- In 1998--99, @email{rsm@@math.arizona.edu, Robert Maier} extracted the
- graphics routines from the sample server code in the X11R6 distribution,
- converted them to @w{ANSI C}, and added extensive comments. @w{He also}
- introduced data structures appropriate for a two-stage graphics
- pipeline, and converted the graphics routines to use them. @w{He added}
- some new rendering features, such as support for multicolored dashing.
- The modified code was first released by being incorporated in version
- 2.2 of the GNU @code{plotutils} package, as a rendering module for
- export of PNM and pseudo-GIF files. See the
- @uref{http://www.gnu.org/software/plotutils/plotutils.html,
- @code{plotutils} home page}. After further modifications, the code was
- released as the standalone @code{libxmi} library.
- @bye
|