This is libxmi.info, produced by makeinfo version 4.7 from libxmi.texi. INFO-DIR-SECTION Libraries START-INFO-DIR-ENTRY * Libxmi: (libxmi). The GNU libxmi 2-D rasterization library. END-INFO-DIR-ENTRY This file documents version 1.3 of the GNU libxmi 2-D rasterization library. Copyright (C) 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.  File: libxmi.info, Node: Top, Next: libxmi Overview, Prev: (dir), Up: (dir) 1 The `libxmi' 2-D Rasterization Library **************************************** This is the documentation for version 1.3 of the GNU `libxmi' 2-D rasterization library, which is used by C and C++ programmers. 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. If the latter, the filling may be a solid color, 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  File: libxmi.info, Node: libxmi Overview, Next: libxmi Example, Prev: Top, Up: Top 1.1 An overview of `libxmi' =========================== With the aid of the GNU `libxmi' library, a C or C++ programmer may rasterize two-dimensional geometric objects; 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 `libxmi' API (application programming interface) are `miDrawPoints', `miDrawLines', `miFillPolygon', `miDrawRectangles', `miFillRectangles', `miDrawArcs', and `miFillArcs'. Each of these takes an array, rather than a single object, as an argument. For example, one of the arguments of `miDrawLines' is an array of points, interpreted as the vertices of a polyline. The polygon filled by `miFillPolygon' is specified similarly. And the final four functions render lists of objects, rather than single objects. Actually, `libxmi' provides a two-stage graphics pipeline. In the first stage, an opaque object called a `miPaintedSet' is drawn onto. Each of the eight drawing functions takes a pointer to a `miPaintedSet' as its first argument. Conceptually, a `miPaintedSet' is an unordered set of points with integer coordinates, partitioned by pixel value. The datatype representing a pixel value is `miPixel', which is normally typedef'd as `unsigned int'. Each of the drawing functions takes a pointer to a `miGC', or graphics context, as its second argument. The `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 `miPaintedSet' acquires the pixel value applied to it in the final drawing operation. In the second stage, more sophisticated pixel-merging algorithms may be applied. In this stage, a `miPaintedSet' is copied (`merged') onto a `miCanvas', by invoking `miCopyPaintedSetToCanvas'. A `miCanvas' is a structure that includes a `miPixmap': a two-dimensional array of `miPixel's that may be initialized by the user, and read, pixel by pixel, after the merging is performed. By default, `miCopyPaintedSetToCanvas' uses the Painter's Algorithm too, so that the source pixel in the `miPaintedSet' replaces the destination pixel in the `miCanvas'. But the merging process may be controlled in much finer detail. A stipple bitmap and a texture pixmap, and binary and ternary pixel-merging functions, may be specified. The _interpretation_ of pixel values is left up to the user. A `miPixel' could be an index into a color table. It could also be an encoding of a color according to the RGB scheme, the RGBA scheme, or some other scheme. Even though a `miPixel' is normally an `unsigned int', this may be altered, if desired, at the time `libxmi' is installed. Any scalar type or nonscalar type, including a structure or a union, could be substituted. `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 `miPixel', it is possible to customize the definition of the `miPixmap' datatype, which by default is an array of pointers to rows of `miPixel's. The default merging algorithm used by `miCopyPaintedSetToCanvas' may also be altered: it need not be the Painter's Algorithm. For instructions on customization, see the comments in the `libxmi' header file `xmi.h'.  File: libxmi.info, Node: libxmi Example, Next: libxmi API, Prev: libxmi Overview, Up: Top 1.2 A sample `libxmi' program ============================= The following C program uses `libxmi' to create a `miPaintedSet', draws a dashed polyline and a dashed elliptic arc on the `miPaintedSet', and transfers the painted pixels to a `miCanvas' that includes a pixmap of specified size. Finally, it writes the pixmap to standard output. #include #include #include /* public libxmi header file */ 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; /* 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; /* 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) */ /* 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 */ dashes[0] = 4; /* length of `on' dashes */ dashes[1] = 2; /* length of `off' dashes */ 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 */ /* create empty painted set */ paintedSet = miNewPaintedSet (); /* paint dashed polyline and dashed arc onto painted set */ miDrawLines (paintedSet, pGC, MI_COORD_MODE_ORIGIN, 4, points); miDrawArcs (paintedSet, pGC, 1, &arc); /* 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); /* 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"); } /* clean up */ miDeleteCanvas (canvas); miDeleteGC (pGC); miClearPaintedSet (paintedSet); /* not necessary */ miDeletePaintedSet (paintedSet); return 0; } This program illustrates how `miPaintedSet', `miGC', and `miCanvas' objects are created and destroyed, as well as manipulated. Each of these types has a constructor and a destructor, named `miNew'... and `miDelete'..., respectively. When creating a `miGC' with `miNewGC', an array of `miPixel's of length at least 2 must be passed as the second argument. The first argument, `npixels', is the length of the array. The default color for drawing operations will be pixel number 1 in the array. The other pixel colors in the array will only be used when dashing. In normal (on/off) dashing, the colors of the `on' dashes will cycle through the colors numbered 1,2,...,npixels-1 in the array. In so-called double dashing, the `off' dashes will be drawn too, in color number 0. In the program, the first call to `miGCSetAttrib' sets the line mode to `MI_LINE_ON_OFF_DASH' rather than `MI_DOUBLE_DASH'. This replaces the default, which is `MI_LINE_SOLID', meaning no dashing (only color number 1 in the pixel array is used). An array of dash lengths is then specified by calling `miSetGCDashes'. (The default dash length array, which is replaced, is `{4,4}'). When dashing, the specified dash length array will be cyclically used. The first dash will be `on', the second `off', and so forth. The third argument to `miSetGCDashes' specifies an initial offset into this cyclic pattern. Currently, the offset must be nonnegative. The second call to `miGCSetAttrib' sets the line width in the graphics context. 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. 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 width 1, and many people prefer them. `miDrawLines' and `miDrawArc' do the actual drawing. They are passed a polyline (i.e., an array of `miPoint's) and a `miArc', respectively. The definitions of the `miPoint' and `miArc' structures appear in the header file `xmi.h', which is worth examining. The third argument of `miDrawLines', `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 `miCanvas', and copies the pixels from it to standard output. A `miCanvas', unlike a `miPaintedSet' and a `miGC', is not an opaque object, so its elements may be read (and written). In fact, a `miCanvas' may be constructed by hand and passed to the `miCopyPaintedSetToCanvas' function. However, it is usually easiest to use the constructor `miNewCanvas' and the destructor `miDeleteCanvas'. Any `miCanvas' created with `miNewCanvas' is allocated on the heap, with `malloc'. It includes a pixmap (an array of `miPixel's, of specified size) that is itself allocated on the heap. It is only when the painted pixels are transferred from `miPaintedSet' to `miCanvas' that clipping to a pixmap takes place. Drawing to a `miPaintedSet' is entirely unclipped: at least in principle, the `miPaintedSet' is of potentially infinite extent. However, the pixmap in the `miCanvas' created by `miNewCanvas (60, 35, 0)' has upper left corner `(0,0)' and lower right corner `(59,34)'. Out-of-bound painted pixels, if any, will not be transferred. The third argument of `miNewCanvas' is its `initPixel' argument: the pixel value to which each `miPixel' in the pixmap is initialized. Since this value is `0', the pixmap that is sent to standard output will display the dashed polyline and arc in the `2', `3', and `4' colors, on a background of zeroes.  File: libxmi.info, Node: libxmi API, Next: Acknowledgements, Prev: libxmi Example, Up: Top 1.3 The `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  File: libxmi.info, Node: Opaque Data Structures, Next: First Stage, Prev: libxmi API, Up: libxmi API 1.3.1 Opaque data structures ---------------------------- The drawing functions used in the first stage of the `libxmi' graphics pipeline paint pixels on a `miPaintedSet'. A `miPaintedSet' should be thought of as an unordered set of points with integer coordinates, partitioned according to pixel value. Any pixel value is a `miPixel', which in most `libxmi' installations is typedef'd as an `unsigned int'. A `miPaintedSet' is an opaque object that must be accessed through a pointer. The functions miPaintedSet * miNewPaintedSet (void); void miDeletePaintedSet (miPaintedSet *paintedSet); are the constructor and destructor for the `miPaintedSet' type. The function void miClearPaintedSet (miPaintedSet *paintedSet); clears all pixels from a `miPaintedSet', i.e., makes it the empty set. All drawing functions that paint pixels on a `miPaintedSet' take a pointer to a graphics context as an argument. A graphics context is an opaque object, called a `miGC', that contains drawing parameters. The functions miGC * miNewGC (int npixels, const miPixel *pixels); void miDeleteGC (miGC *pGC); miGC * miCopyGC (const miGC *pGC); are the constructor, destructor, and copy constructor for the `miGC' type. The arguments of `miNewGC' specify an array of `miPixel's, which must have length at least 2. The default color for drawing operations will be pixel number 1 in the array. The other pixel colors in the array will only be used when dashing. In normal (on/off) dashing, the colors of the `on' dashes will cycle through the colors numbered 1,2,...,npixels-1. In so-called double dashing, the `off' dashes will be drawn too, in color number 0. The array of pixel colors may be modified at any later time, by invoking the function `miSetGCPixels'. void miSetGCPixels (miGC *pGC, int npixels, const miPixel *pixels); is the declaration of this function. The lengths of dashes, when dashing, may be set by invoking `miSetGCDashes'. It has declaration void miSetGCDashes (miGC *pGC, int ndashes, const unsigned int *dashes, int offset); Here `dashes' is an array of length `ndashes'. The array is cyclically used. The first dash in a polyline or arc will be an `on' dash of length `dashes[0]'; the next dash will be an `off' dash of length `dashes[1]'; and so forth. The default dash length array in any `miGC' is `{4,4}'. The dash length array need not have the same length as the pixel color array, and it need not have even length. `offset', if nonzero, is an initial offset into the dash pattern. For example, if it equals `dashes[0]' then the first dash will be an `off' dash of length `dashes[1]'. Currently, `offset' must be nonnegative. Besides the array of pixel colors and the array of dash lengths, any `miGC' contains several attributes whose values are `enum's, and an integer-valued line width attribute. Any one of these may be set by invoking `miSetGCAttrib', and any list of them by invoking `miSetGCAttribs'. The declarations of these functions are: 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; void miSetGCAttrib (miGC *pGC, miGCAttribute attribute, int value); void miSetGCAttribs (miGC *pGC, int nattributes, const miGCAttribute *attributes, const int *values); These attributes are similar to the drawing attributes used in the X Window System. The allowed values for the attribute `MI_GC_FILL_RULE', which specifies the rule used when filling polygons and arcs, are: enum { MI_EVEN_ODD_RULE, MI_WINDING_RULE }; The default is `MI_EVEN_ODD_RULE'. The allowed values for the attribute `MI_GC_JOIN_STYLE', which specifies the rule used when joining polylines and polyarcs, are: enum { MI_JOIN_MITER, MI_JOIN_ROUND, MI_JOIN_BEVEL, MI_JOIN_TRIANGULAR }; The default is `MI_JOIN_MITER'. The allowed values for the attribute `MI_GC_CAP_STYLE', which specifies the rule used when capping the ends of polylines and arcs, are: enum { MI_CAP_NOT_LAST, MI_CAP_BUTT, MI_CAP_ROUND, MI_CAP_PROJECTING, MI_CAP_TRIANGULAR }; The default is `MI_CAP_BUTT'. The allowed values for the attribute `MI_GC_LINE_STYLE', which specifies whether or not dashing should take place when drawing polylines and arcs, are: enum { MI_LINE_SOLID, MI_LINE_ON_OFF_DASH, MI_LINE_DOUBLE_DASH }; The default is `MI_LINE_SOLID'. The allowed values for the attribute `MI_GC_ARC_MODE', which specifies how arcs should be filled, are: enum { MI_ARC_CHORD, MI_ARC_PIE_SLICE }; The default is `MI_ARC_PIE_SLICE'. Finally, the value for the line width, i.e., for the `MI_GC_LINE_WIDTH' attribute, may be any nonnegative integer. The default 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 width 1. Any `miGC' also contains a miter-limit attribute, which, if the join mode attribute has value `MI_JOIN_MITER' and the line width is at least 1, will affect the drawing of the joins in polylines and polyarcs. 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. If this value is exceeded, the miter will be `cut off': the `MI_JOIN_BEVEL' join mode will be used instead. The function void miSetGCMiterLimit (miGC *pGC, double miter_limit); sets the value of this attribute. The specified value must be greater than or equal 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 than 1.0 are meaningless. The default value for the miter limit is 10.43, as in the X Window System. 10.43 is the cosecant of 5.5 degrees, so by default, miters will be cut off if the join angle is less than 11 degrees.  File: libxmi.info, Node: First Stage, Next: Second Stage, Prev: Opaque Data Structures, Up: libxmi API 1.3.2 The first stage of the graphics pipeline ---------------------------------------------- In the first stage of the `libxmi' graphics pipeline, one or more of the core drawing functions is invoked. Each drawing function takes pointers to a `miPaintedSet' and a `miGC' (a graphics context) as its first and second arguments. It will paint pixels in the `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, (2) functions that draw rectangles, and (3) functions that draw `arcs' (segments of ellipses whose principal axes are aligned with the coordinate axes). We discuss these three groups in turn. The point/polyline/polygon group includes: 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); The final three arguments of each are a coordinate mode, a specified number of points, and an array that contains that number of points. `miDrawPoints' draws the array as a cloud of points, `miDrawLines' draws a polyline defined by the array, and `miFillPolygon' fills a polygon defined by the array. The `mode' argument specifies whether the points in the array, after the first, are in absolute or relative coordinates. Its possible values are: typedef enum { MI_COORD_MODE_ORIGIN, MI_COORD_MODE_PREVIOUS } miCoordMode; The `miPoint' structure is defined by typedef struct { int x, y; /* integer coordinates, y goes downward */ } miPoint; The additional `shape' argument of `miFillPolygon' is advisory. Its possible values are: typedef enum { MI_SHAPE_GENERAL, MI_SHAPE_CONVEX } miPolygonShape; They indicate whether the polygon is (1) unconstrained (i.e., not necessarily convex, with self-intersections allowed), or (2) convex and not self-intersecting. The latter case can be drawn more rapidly. The rectangle group includes void miDrawRectangles (miPaintedSet *paintedSet, const miGC *pGC, int nrects, const miRectangle *pRects); void miFillRectangles (miPaintedSet *paintedSet, const miGC *pGC, int nrects, const miRectangle *pRects); The final two arguments of each are a specified number of rectangles and an array that contains that number of rectangles. `miDrawRectangles' draws the outline of each rectangle, and `miFillRectangle' fills each rectangle. The `miRectangle' structure is defined by typedef struct { int x, y; /* upper left corner of rectangle */ unsigned int width, height; /* dimensions: width>=1, height>=1 */ } miRectangle; 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 void miDrawArcs (miPaintedSet *paintedSet, const miGC *pGC, int narcs, const miArc *parcs); void miFillArcs (miPaintedSet *paintedSet, const miGC *pGC, int narcs, const miArc *parcs); The final two arguments of each are a specified number of arcs and an array that contains that number of arcs. `miDrawArcs' draws each arc. It will join successive arcs, if they are contiguous, according to the `join mode' in the graphics context. Similarly, `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 `miArc' structure is defined by 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; `x', `y', `width', `height' specify a rectangle aligned with the coordinate axes, and `angle1', `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. `miDrawArcs' maintains a cache of rasterized ellipses. This cache is persistent, and internal to `libxmi'; accordingly, `miDrawArcs' is not reentrant. For applications in which reentrancy is important, a reentrant counterpart is provided. It is void miDrawArcs_r (miPaintedSet *paintedSet, const miGC *pGC, int narcs, const miArc *parcs, miEllipseCache *ellipseCache); The caller of `miDrawArcs_r' must supply a pointer to a `miEllipseCache' object as the final argument. A pointer to such an object, which is opaque, is returned by `miNewEllipseCache'. After zero or more calls to `miDrawArcs_r', the object would be deleted by a call to `miDeleteEllipseCache'. The declarations miEllipseCache * miNewEllipseCache (void); void miDeleteEllipseCache (miEllipseCache *ellipseCache); are supplied in the header file `xmi.h'.  File: libxmi.info, Node: Second Stage, Prev: First Stage, Up: libxmi API 1.3.3 The second stage of the graphics pipeline ----------------------------------------------- In the second state of the graphics pipeline, the pixels in a `miPaintedSet' are transferred (`merged') to a `miCanvas', by invoking `miCopyPaintedSetToCanvas'. It is only when the painted pixels are transferred to a `miCanvas' that clipping to a pixmap takes place. A `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 by hand, if necessary. The `miCanvas' type has definition typedef struct { miCanvasPixmap *drawable; /* the pixmap */ miBitmap *stipple; /* a mask, if non-NULL */ miPoint stippleOrigin; /* placement of upper left corner */ miPixmap *texture; /* a texture, if non-NULL */ miPoint textureOrigin; /* placement of upper left corner */ miPixelMerge2 pixelMerge2; /* binary merging function, if non-NULL */ miPixelMerge3 pixelMerge3; /* ternary counterpart, if non-NULL */ } miCanvas; Here, the `miBitmap' and `miPixmap' types are defined by typedef struct { int **bitmap; /* each element is 0 or 1 */ unsigned int width; unsigned int height; } miBitmap; typedef struct { miPixel **pixmap; /* each element is a miPixel */ unsigned int width; unsigned int height; } miPixmap; That is, each of them contains an array of pointers to rows (of integers or pixel values, as the case may be). In most installations of `libxmi', `miCanvasPixmap' is typedef'd as `miPixmap'. The typedefs typedef miPixel (*miPixelMerge2) (miPixel source, miPixel destination); typedef miPixel (*miPixelMerge3) (miPixel texture, miPixel source, miPixel destination); define the datatypes of the binary and ternary pixel-merging function members. The functions miCanvas * miNewCanvas (unsigned int width, unsigned int height, miPixel initPixel); void miDeleteCanvas (miCanvas *pCanvas); miCanvas * miCopyCanvas (const miCanvas *pCanvas); are the constructor, destructor, and copy constructor for the `miCanvas' type. Rather than a `miCanvas' being created by hand, `miNewCanvas' is usually used instead. The `initPixel' argument is a `miPixel' value with which the newly allocated pixmap should be filled. The `stipple' and `texture' pointers in a newly created `miCanvas' are `NULL', as are the pixel-merging function members. The four convenience functions void miSetCanvasStipple (miCanvas *pCanvas, const miBitmap *pStipple, miPoint stippleOrigin); void miSetCanvasTexture (miCanvas *pCanvas, const miPixmap *pTexture, miPoint textureOrigin); void miSetPixelMerge2 (miCanvas *pCanvas, miPixelMerge2 pixelMerge2); void miSetPixelMerge3 (miCanvas *pCanvas, miPixelMerge3 pixelMerge3); may be used to set these members. The `miCopyPaintedSetToCanvas' function, which implements the second stage of the graphics pipeline, can now be discussed. It has declaration void miCopyPaintedSetToCanvas (const miPaintedSet *paintedSet, miCanvas *canvas, miPoint origin); where `origin' is the point on the `miCanvas' to which the point `(0,0)' in the `miPaintedSet' is mapped. (It could equally well be called `offset'.) The semantics of `miCopyPaintedSet' boil down to a single issue: how a `source' pixel in a `miPaintedSet' is merged onto the corresponding `destination' pixel in a `miCanvas' to form a new pixel. The simplest case is when no texture is specified (the corresponding pointer in the `miCanvas' is `NULL'). In that case, if the binary pixel-merging function member of the `miCanvas' is `NULL', a default merging algorithm will be used. In most `libxmi' installations this is the Painter's Algorithm: the new pixel in the `miCanvas' will simply be the source pixel. If, on the other hand, the binary pixel-merging function in the `miCanvas' is non-`NULL', 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 `miCanvas', and its value at the location of the destination pixel will affect the merging process. If the ternary pixel-merging function member of the `miCanvas' is `NULL', a default merging algorithm, appropriate to the case when a texture is present, will be used. In most `libxmi' installations this is a variant of the Painter's Algorithm: the new pixel in the `miCanvas' will be the texture pixel, rather than the source pixel. If, on the other hand, the ternary pixel-merging function in the `miCanvas' is non-`NULL', it will be used to compute the new pixel. Any `miCanvas' may also include a pointer to a stipple bitmap. If so, it will be extended periodically so as to cover the `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. If the stipple value is zero, it will not; otherwise it will. Stipple bitmaps are useful for creating so-called screen door patterns, and more generally for protecting, or masking off, part of a `miCanvas'.  File: libxmi.info, Node: Acknowledgements, Prev: libxmi API, Up: Top Acknowledgements **************** `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 X Consortium, and are copyright (C) 1985-89 by the X Consortium. In 1998-99, Robert Maier extracted the graphics routines from the sample server code in the X11R6 distribution, converted them to ANSI C, and added extensive comments. He also introduced data structures appropriate for a two-stage graphics pipeline, and converted the graphics routines to use them. 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 `plotutils' package, as a rendering module for export of PNM and pseudo-GIF files. See the `plotutils' home page (http://www.gnu.org/software/plotutils/plotutils.html). After further modifications, the code was released as the standalone `libxmi' library.  Tag Table: Node: Top1013 Node: libxmi Overview1953 Node: libxmi Example5823 Node: libxmi API13111 Node: Opaque Data Structures13462 Node: First Stage19709 Node: Second Stage25313 Node: Acknowledgements30847  End Tag Table