libxmi.texi 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. \input texinfo @c -*-texinfo-*-
  2. @c %**start of header
  3. @setfilename libxmi.info
  4. @settitle The GNU @code{libxmi} 2-D Rasterization Library
  5. @c For double-sided printing, uncomment:
  6. @c @setchapternewpage odd
  7. @c %**end of header
  8. @dircategory Libraries
  9. @direntry
  10. * Libxmi: (libxmi). The GNU libxmi 2-D rasterization library.
  11. @end direntry
  12. @ifinfo
  13. This file documents version 1.3 of the GNU libxmi 2-D rasterization library.
  14. Copyright @copyright{} 1998--2005 Free Software Foundation, Inc.
  15. Permission is granted to make and distribute verbatim copies of
  16. this manual provided the copyright notice and this permission notice
  17. are preserved on all copies.
  18. Permission is granted to copy and distribute modified versions of this
  19. manual under the conditions for verbatim copying, provided that the entire
  20. resulting derived work is distributed under the terms of a permission
  21. notice identical to this one.
  22. Permission is granted to copy and distribute translations of this manual
  23. into another language, under the above conditions for modified versions,
  24. except that this permission notice may be stated in a translation approved
  25. by the Foundation.
  26. @end ifinfo
  27. @titlepage
  28. @title The GNU @code{libxmi} 2-D Rasterization Library
  29. @subtitle Version 1.3
  30. @author Robert S. Maier
  31. @page
  32. @vskip 0pt plus 1filll
  33. Copyright @copyright{} 1998--1999 Free Software Foundation, Inc.
  34. Permission is granted to make and distribute verbatim copies of
  35. this manual provided the copyright notice and this permission notice
  36. are preserved on all copies.
  37. Permission is granted to copy and distribute modified versions of this
  38. manual under the conditions for verbatim copying, provided that the entire
  39. resulting derived work is distributed under the terms of a permission
  40. notice identical to this one.
  41. Permission is granted to copy and distribute translations of this manual
  42. into another language, under the above conditions for modified versions,
  43. except that this permission notice may be stated in a translation approved
  44. by the Foundation.
  45. @end titlepage
  46. @page
  47. @node Top, libxmi Overview, (dir), (dir)
  48. @chapter The @code{libxmi} 2-D Rasterization Library
  49. This is the documentation for version 1.3 of the GNU @code{libxmi} 2-D
  50. rasterization library, which is used by @w{C and} C++ programmers.
  51. @w{It converts} 2-D geometrical objects, such as polylines, polygons,
  52. and arcs, to raster patterns. There is support for setting drawing
  53. attributes, including line width, join style, cap style, and a
  54. multicolored dash pattern. The objects may be unfilled or filled.
  55. @w{If the latter}, the filling may be a solid color, @w{a stipple}
  56. pattern, or a texture. There is support for sophisticated color-merging
  57. between separately drawn objects.
  58. @menu
  59. * libxmi Overview:: GNU libxmi and its features
  60. * libxmi Example:: A sample program that may be linked with libxmi
  61. * libxmi API:: The libxmi API
  62. * Acknowledgements:: The contributors
  63. @end menu
  64. @node libxmi Overview, libxmi Example, Top, Top
  65. @section An overview of @code{libxmi}
  66. With the aid of the GNU @code{libxmi} library, a C or C++ programmer may
  67. rasterize two-dimensional geometric objects; @w{that is}, draw them on a
  68. two-dimensional array of pixels. The supported objects are points,
  69. polylines, filled polylines (i.e., polygons), rectangles, filled
  70. rectangles, and `arcs': segments of ellipses whose principal axes are
  71. aligned with the coordinate axes. Like polylines and rectangles, arcs
  72. may be unfilled or filled.
  73. The corresponding rendering functions in the @code{libxmi} API
  74. (application programming interface) are @code{miDrawPoints},
  75. @code{miDrawLines}, @code{miFillPolygon}, @code{miDrawRectangles},
  76. @code{miFillRectangles}, @code{miDrawArcs}, and @code{miFillArcs}. Each
  77. of these takes an array, rather than a single object, as an argument.
  78. For example, one of the arguments of @code{miDrawLines} is an array of
  79. points, interpreted as the vertices of a polyline. The polygon filled
  80. by @code{miFillPolygon} is specified similarly. And the final four
  81. functions render lists of objects, rather than single objects.
  82. Actually, @code{libxmi} provides a two-stage graphics pipeline. In the
  83. first stage, an opaque object called a @code{miPaintedSet} is drawn
  84. onto. Each of the eight drawing functions takes a pointer to a
  85. @code{miPaintedSet} as its first argument. Conceptually, a
  86. @code{miPaintedSet} is an unordered set of points with integer
  87. coordinates, partitioned by pixel value. The datatype representing a
  88. pixel value is @code{miPixel}, which is normally typedef'd as
  89. @code{unsigned int}. Each of the drawing functions takes a pointer to a
  90. @code{miGC}, or graphics context, as its second argument. The
  91. @code{miGC} specifies such drawing attributes as line width, join style,
  92. cap style, and dashing style, and also the pixel value(s) to be used in
  93. the painting operation.
  94. In the first stage of the pipeline the Painter's Algorithm is used, so
  95. that a repeatedly-painted point in a @code{miPaintedSet} acquires the
  96. pixel value applied @w{to it} in the final drawing operation. In the
  97. second stage, more sophisticated pixel-merging algorithms may be
  98. applied. @w{In this} stage, a @code{miPaintedSet} is copied (`merged')
  99. onto a @code{miCanvas}, by invoking @code{miCopyPaintedSetToCanvas}.
  100. @w{A @code{miCanvas}} is a structure that includes a @code{miPixmap}: a
  101. two-dimensional array of @code{miPixel}s that may be initialized by the
  102. user, and read, pixel by pixel, after the merging is performed. By
  103. default, @code{miCopyPaintedSetToCanvas} uses the Painter's Algorithm
  104. too, so that the source pixel in the @code{miPaintedSet} replaces the
  105. destination pixel in the @code{miCanvas}. But the merging process may
  106. be controlled in much finer detail. @w{A stipple} bitmap and a texture
  107. pixmap, and binary and ternary pixel-merging functions, may be
  108. specified.
  109. The @emph{interpretation} of pixel values is left @w{up to} the user.
  110. @w{A @code{miPixel}} could be an index into a color table. @w{It could}
  111. also be an encoding of a color according to the RGB scheme, the RGBA
  112. scheme, or some other scheme. Even though a @code{miPixel} is normally
  113. an @code{unsigned int}, this may be altered, if desired, at the time
  114. @code{libxmi} is installed. Any scalar type or nonscalar type,
  115. including a structure or a union, could be substituted.
  116. @code{libxmi} is intended for use both as a standalone library and as a
  117. rendering module that may be incorporated in other packages. To
  118. facilitate its use in other packages, it may be extensively customized
  119. at installation time. Besides customizing the definition of
  120. @code{miPixel}, it is possible to customize the definition of the
  121. @code{miPixmap} datatype, which by default is an array of pointers to
  122. rows of @code{miPixel}s. The default merging algorithm used by
  123. @code{miCopyPaintedSetToCanvas} may also be altered: @w{it need} not be
  124. the Painter's Algorithm. For instructions on customization, see the
  125. comments in the @code{libxmi} header file @file{xmi.h}.
  126. @node libxmi Example, libxmi API, libxmi Overview, Top
  127. @section A sample @code{libxmi} program
  128. The following C program uses @code{libxmi} to create a
  129. @code{miPaintedSet}, draws a dashed polyline and a dashed elliptic arc
  130. on the @code{miPaintedSet}, and transfers the painted pixels to a
  131. @code{miCanvas} that includes a pixmap of specified size. Finally, it
  132. writes the pixmap to standard output.
  133. @example
  134. @group
  135. #include <stdio.h>
  136. #include <stdlib.h>
  137. #include <xmi.h> /* public libxmi header file */
  138. @end group
  139. @group
  140. int main ()
  141. @{
  142. miPoint points[4]; /* 3 line segments in the polyline */
  143. miArc arc; /* 1 arc to be drawn */
  144. miPixel pixels[4]; /* pixel values for drawing and dashing */
  145. unsigned int dashes[2]; /* length of `on' and `off' dashes */
  146. miGC *pGC; /* graphics context */
  147. miPaintedSet *paintedSet; /* opaque object to be painted */
  148. miCanvas *canvas; /* drawing canvas (including pixmap) */
  149. miPoint offset; /* for miPaintedSet -> miCanvas transfer */
  150. int i, j;
  151. @end group
  152. @group
  153. /* define polyline: vertices are (25,5) (5,5), (5,25), (35,22) */
  154. points[0].x = 25; points[0].y = 5;
  155. points[1].x = 5; points[1].y = 5;
  156. points[2].x = 5; points[2].y = 25;
  157. points[3].x = 35; points[3].y = 22;
  158. @end group
  159. @group
  160. /* define elliptic arc */
  161. arc.x = 20; arc.y = 15; /* upper left corner of bounding box */
  162. arc.width = 30; /* x range of box: 20..50 */
  163. arc.height = 16; /* y range of box: 15..31 */
  164. arc.angle1 = 0 * 64; /* starting angle (1/64'ths of a degree) */
  165. arc.angle2 = 270 * 64; /* angle range (1/64'ths of a degree) */
  166. @end group
  167. @group
  168. /* create and modify graphics context */
  169. pixels[0] = 1; /* pixel value for `off' dashes, if drawn */
  170. pixels[1] = 2; /* default pixel for drawing */
  171. pixels[2] = 3; /* another pixel, for multicolored dashes */
  172. pixels[3] = 4; /* another pixel, for multicolored dashes */
  173. @end group
  174. @group
  175. dashes[0] = 4; /* length of `on' dashes */
  176. dashes[1] = 2; /* length of `off' dashes */
  177. @end group
  178. @group
  179. pGC = miNewGC (4, pixels);
  180. miSetGCAttrib (pGC, MI_GC_LINE_STYLE, MI_LINE_ON_OFF_DASH);
  181. miSetGCDashes (pGC, 2, dashes, 0);
  182. miSetGCAttrib (pGC, MI_GC_LINE_WIDTH, 0); /* Bresenham algorithm */
  183. @end group
  184. @group
  185. /* create empty painted set */
  186. paintedSet = miNewPaintedSet ();
  187. @end group
  188. @group
  189. /* paint dashed polyline and dashed arc onto painted set */
  190. miDrawLines (paintedSet, pGC, MI_COORD_MODE_ORIGIN, 4, points);
  191. miDrawArcs (paintedSet, pGC, 1, &arc);
  192. @end group
  193. @group
  194. /* create 60x35 canvas (initPixel=0); merge painted set onto it */
  195. canvas = miNewCanvas (60, 35, 0);
  196. offset.x = 0; offset.y = 0;
  197. miCopyPaintedSetToCanvas (paintedSet, canvas, offset);
  198. @end group
  199. @group
  200. /* write canvas's pixmap (a 60x35 array of miPixels) to stdout */
  201. for (j = 0; j < canvas->drawable->height; j++)
  202. @{
  203. for (i = 0; i < canvas->drawable->width; i++)
  204. /* note: column index precedes row index */
  205. printf ("%d", canvas->drawable->pixmap[j][i]);
  206. printf ("\n");
  207. @}
  208. @end group
  209. @group
  210. /* clean up */
  211. miDeleteCanvas (canvas);
  212. miDeleteGC (pGC);
  213. miClearPaintedSet (paintedSet); /* not necessary */
  214. miDeletePaintedSet (paintedSet);
  215. @end group
  216. @group
  217. return 0;
  218. @}
  219. @end group
  220. @end example
  221. This program illustrates how @code{miPaintedSet}, @code{miGC}, and
  222. @code{miCanvas} objects are created and destroyed, @w{as well} as
  223. manipulated. Each of these types has a constructor and a destructor,
  224. named @code{miNew}@dots{} and @code{miDelete}@dots{}, respectively.
  225. When creating a @code{miGC} with @code{miNewGC}, an array of
  226. @code{miPixel}s of length at @w{least 2} must be passed as the second
  227. argument. The first argument, @code{npixels}, is the length of the
  228. array. The default color for drawing operations will be pixel @w{number
  229. 1} in the array. The other pixel colors in the array will only be used
  230. when dashing. @w{In normal} (on/off) dashing, the colors of the `on'
  231. dashes will cycle through the colors numbered 1,2,@dots{},npixels-1 in
  232. the array. In so-called double dashing, the `off' dashes will be drawn
  233. too, in color @w{number 0}.
  234. In the program, the first call to @code{miGCSetAttrib} sets the line
  235. mode to @code{MI_LINE_ON_OFF_DASH} rather than @code{MI_DOUBLE_DASH}@.
  236. This replaces the default, which is @code{MI_LINE_SOLID}, meaning no
  237. dashing (only color @w{number 1} in the pixel array is used). @w{An
  238. array} of dash lengths is then specified by calling
  239. @code{miSetGCDashes}. (The default dash length array, which is
  240. replaced, is @code{@{4,4@}}). When dashing, the specified dash length
  241. array will be cyclically used. The first dash will be `on', the second
  242. `off', and @w{so forth}. The third argument to @code{miSetGCDashes}
  243. specifies an initial offset into this cyclic pattern. Currently, the
  244. offset must be nonnegative.
  245. The second call to @code{miGCSetAttrib} sets the line width in the
  246. graphics context. @w{If the} specified line width is positive, lines
  247. and arcs will be drawn with a circular brush whose diameter is equal to
  248. the line width. All pixels within the brushed region will be painted.
  249. @w{If the} line width is zero, as it is here, a so-called Bresenham
  250. algorithm will be used. Bresenham lines and arcs are drawn with fewer
  251. pixels than is the case for lines and arcs with @w{width 1}, and many
  252. people prefer them.
  253. @code{miDrawLines} and @code{miDrawArc} do the actual drawing. They are
  254. passed a polyline (i.e., an array of @code{miPoint}s) and a
  255. @code{miArc}, respectively. The definitions of the @code{miPoint} and
  256. @code{miArc} structures appear in the header file @file{xmi.h}, which is
  257. worth examining. The third argument of @code{miDrawLines},
  258. @code{MI_COORD_MODE_ORIGIN}, specifies that the points of the polyline,
  259. after the first, are expressed in absolute rather than relative
  260. coordinates.
  261. Finally, the program transfers the painted pixels to a @code{miCanvas},
  262. and copies the pixels from it to standard output. @w{A
  263. @code{miCanvas}}, unlike a @code{miPaintedSet} and a @code{miGC}, is not
  264. an opaque object, so its elements may be read (and written). @w{In
  265. fact}, a @code{miCanvas} may be constructed by hand and passed to the
  266. @code{miCopyPaintedSetToCanvas} function. However, it is usually
  267. easiest to use the constructor @code{miNewCanvas} and the destructor
  268. @code{miDeleteCanvas}. Any @code{miCanvas} created with
  269. @code{miNewCanvas} is allocated on the heap, with @code{malloc}. @w{It
  270. includes} a pixmap (@w{an array} of @code{miPixel}s, of specified size)
  271. that is itself allocated on the heap.
  272. It is only when the painted pixels are transferred from
  273. @code{miPaintedSet} to @code{miCanvas} that clipping to a pixmap takes
  274. place. Drawing to a @code{miPaintedSet} is entirely unclipped: @w{at
  275. least} in principle, the @code{miPaintedSet} is of potentially infinite
  276. extent. However, the pixmap in the @code{miCanvas} created by
  277. @code{miNewCanvas (60, 35, 0)} has upper left corner @code{(0,0)} and
  278. lower right corner @code{(59,34)}. Out-of-bound painted pixels, @w{if
  279. any}, will not be transferred.
  280. The third argument of @code{miNewCanvas} is its @code{initPixel}
  281. argument: the pixel value @w{to which} each @code{miPixel} in the pixmap
  282. is initialized. Since this value @w{is `0'}, the pixmap that is sent to
  283. standard output will display the dashed polyline and arc in the `2',
  284. `3', @w{and `4'} colors, on a background of zeroes.
  285. @node libxmi API, Acknowledgements, libxmi Example, Top
  286. @section The @code{libxmi} API
  287. @menu
  288. * Opaque Data Structures:: The miPaintedSet and miGC structures
  289. * First Stage:: Painting pixels in a miPaintedSet
  290. * Second Stage:: Merging a miPaintedSet onto a miCanvas
  291. @end menu
  292. @node Opaque Data Structures, First Stage, libxmi API, libxmi API
  293. @subsection Opaque data structures
  294. The drawing functions used in the first stage of the @code{libxmi}
  295. graphics pipeline paint pixels on a @code{miPaintedSet}.
  296. A @code{miPaintedSet} should be thought of as an unordered set of points
  297. with integer coordinates, partitioned according to pixel value. Any
  298. pixel value is a @code{miPixel}, which in most @code{libxmi}
  299. installations is typedef'd as an @code{unsigned int}.
  300. A @code{miPaintedSet} is an opaque object that must be accessed through
  301. a pointer. The functions
  302. @example
  303. @group
  304. miPaintedSet * miNewPaintedSet (void);
  305. void miDeletePaintedSet (miPaintedSet *paintedSet);
  306. @end group
  307. @end example
  308. @noindent
  309. are the constructor and destructor for the @code{miPaintedSet} type.
  310. The function
  311. @example
  312. void miClearPaintedSet (miPaintedSet *paintedSet);
  313. @end example
  314. @noindent
  315. clears all pixels from a @code{miPaintedSet}, i.e., makes it the empty
  316. set.
  317. All drawing functions that paint pixels on a @code{miPaintedSet} take a
  318. pointer to a graphics context as an argument. @w{A graphics} context is
  319. an opaque object, called a @code{miGC}, that contains drawing
  320. parameters. The functions
  321. @example
  322. @group
  323. miGC * miNewGC (int npixels, const miPixel *pixels);
  324. void miDeleteGC (miGC *pGC);
  325. miGC * miCopyGC (const miGC *pGC);
  326. @end group
  327. @end example
  328. @noindent
  329. are the constructor, destructor, and copy constructor for the
  330. @code{miGC} type. The arguments of @code{miNewGC} specify an array of
  331. @code{miPixel}s, which must have length at @w{least 2}. The default
  332. color for drawing operations will be pixel @w{number 1} in the array.
  333. The other pixel colors in the array will only be used when dashing.
  334. @w{In normal} (on/off) dashing, the colors of the `on' dashes will cycle
  335. through the colors numbered 1,2,@dots{},npixels-1. In so-called double
  336. dashing, the `off' dashes will be drawn too, in color @w{number 0}.
  337. The array of pixel colors may be modified at any later time, by invoking
  338. the function @code{miSetGCPixels}.
  339. @example
  340. void miSetGCPixels (miGC *pGC, int npixels, const miPixel *pixels);
  341. @end example
  342. @noindent
  343. is the declaration of this function.
  344. The lengths of dashes, when dashing, may be set by invoking
  345. @code{miSetGCDashes}. It has declaration
  346. @example
  347. void miSetGCDashes (miGC *pGC, int ndashes, const unsigned int *dashes,
  348. int offset);
  349. @end example
  350. @noindent
  351. Here @code{dashes} is an array of length @code{ndashes}. The array is
  352. cyclically used. The first dash in a polyline or arc will be an `on'
  353. dash of length @code{dashes[0]}; the next dash will be an `off' dash of
  354. length @code{dashes[1]}; and so forth. The default dash length array in
  355. any @code{miGC} is @code{@{4,4@}}. The dash length array need not have
  356. the same length as the pixel color array, and it need not have even
  357. length. @code{offset}, if nonzero, is an initial offset into the dash
  358. pattern. For example, if it equals @code{dashes[0]} then the first dash
  359. will be an `off' dash of length @code{dashes[1]}. Currently,
  360. @code{offset} must be nonnegative.
  361. Besides the array of pixel colors and the array of dash lengths, any
  362. @code{miGC} contains several attributes whose values are @code{enum}s,
  363. and an integer-valued line width attribute. Any one of these may be set
  364. by invoking @code{miSetGCAttrib}, and any list of them by invoking
  365. @code{miSetGCAttribs}. The declarations of these functions are:
  366. @example
  367. typedef enum @{ MI_GC_FILL_RULE, MI_GC_JOIN_STYLE, MI_GC_CAP_STYLE,
  368. MI_GC_LINE_STYLE, MI_GC_ARC_MODE, MI_GC_LINE_WIDTH
  369. @} miGCAttribute;
  370. @group
  371. void miSetGCAttrib (miGC *pGC, miGCAttribute attribute, int value);
  372. void miSetGCAttribs (miGC *pGC, int nattributes,
  373. const miGCAttribute *attributes,
  374. const int *values);
  375. @end group
  376. @end example
  377. @noindent
  378. These attributes are similar to the drawing attributes used in the @w{X
  379. Window} System. The allowed values for the attribute
  380. @code{MI_GC_FILL_RULE}, which specifies the rule used when filling
  381. polygons and arcs, are:
  382. @example
  383. enum @{ MI_EVEN_ODD_RULE, MI_WINDING_RULE @};
  384. @end example
  385. @noindent
  386. The default is @code{MI_EVEN_ODD_RULE}@. The allowed values for the
  387. attribute @code{MI_GC_JOIN_STYLE}, which specifies the rule used when
  388. joining polylines and polyarcs, are:
  389. @example
  390. enum @{ MI_JOIN_MITER, MI_JOIN_ROUND, MI_JOIN_BEVEL,
  391. MI_JOIN_TRIANGULAR @};
  392. @end example
  393. @noindent
  394. The default is @code{MI_JOIN_MITER}@. The allowed values for the
  395. attribute @code{MI_GC_CAP_STYLE}, which specifies the rule used when
  396. capping the ends of polylines and arcs, are:
  397. @example
  398. enum @{ MI_CAP_NOT_LAST, MI_CAP_BUTT, MI_CAP_ROUND, MI_CAP_PROJECTING,
  399. MI_CAP_TRIANGULAR @};
  400. @end example
  401. @noindent
  402. The default is @code{MI_CAP_BUTT}@. The allowed values for the
  403. attribute @code{MI_GC_LINE_STYLE}, which specifies whether or not
  404. dashing should take place when drawing polylines and arcs, are:
  405. @example
  406. enum @{ MI_LINE_SOLID, MI_LINE_ON_OFF_DASH, MI_LINE_DOUBLE_DASH @};
  407. @end example
  408. @noindent
  409. The default is @code{MI_LINE_SOLID}@. The allowed values for the
  410. attribute @code{MI_GC_ARC_MODE}, which specifies how arcs should be
  411. filled, are:
  412. @example
  413. enum @{ MI_ARC_CHORD, MI_ARC_PIE_SLICE @};
  414. @end example
  415. @noindent
  416. The default is @code{MI_ARC_PIE_SLICE}@.
  417. Finally, the value for the line width, i.e., for the
  418. @code{MI_GC_LINE_WIDTH} attribute, may be any nonnegative integer. The
  419. default @w{is 0}, which has a special meaning. Zero-width lines and
  420. arcs are not invisible. Instead, they are drawn with a Bresenham
  421. algorithm, which paints fewer pixels than is the case for lines with
  422. @w{width 1}.
  423. Any @code{miGC} also contains a miter-limit attribute, which, if the
  424. join mode attribute has value @code{MI_JOIN_MITER} and the line width is
  425. at @w{least 1}, will affect the drawing of the joins in polylines and
  426. polyarcs. @w{At any} join point, the `miter length' is the distance
  427. between the inner corner and the outer corner. The miter limit is the
  428. maximum value that can be tolerated for the miter length divided by the
  429. line width. @w{If this} value is exceeded, the miter will be `@w{cut
  430. off}': the @code{MI_JOIN_BEVEL} join mode will be used instead.
  431. The function
  432. @example
  433. void miSetGCMiterLimit (miGC *pGC, double miter_limit);
  434. @end example
  435. @noindent
  436. sets the value of this attribute. The specified value must be greater
  437. than or equal @w{to 1.0}. That is because the miter limit is the
  438. cosecant of one-half of the minimum join angle for mitering, so values
  439. less @w{than 1.0} are meaningless. The default value for the miter
  440. limit is 10.43, as in the @w{X Window} System. @w{10.43 is} the
  441. cosecant of 5.5 degrees, so by default, miters will be @w{cut off} if
  442. the join angle is less than @w{11 degrees}.
  443. @node First Stage, Second Stage, Opaque Data Structures, libxmi API
  444. @subsection The first stage of the graphics pipeline
  445. In the first stage of the @code{libxmi} graphics pipeline, one or more
  446. of the core drawing functions is invoked. Each drawing function takes
  447. pointers to a @code{miPaintedSet} and a @code{miGC} (@w{a graphics}
  448. context) as its first and second arguments. @w{It will} paint pixels in
  449. the @code{miPaintedSet}, according to the drawing parameters in the
  450. graphics context.
  451. The drawing functions fall into three groups: (1) functions that draw
  452. points, polylines, and polygons, @w{(2) functions} that draw rectangles,
  453. and @w{(3) functions} that draw `arcs' (segments of ellipses whose
  454. principal axes are aligned with the coordinate axes). @w{We discuss}
  455. these three groups @w{in turn}.
  456. The point/polyline/polygon group includes:
  457. @example
  458. void miDrawPoints (miPaintedSet *paintedSet, const miGC *pGC,
  459. miCoordMode mode, int npts, const miPoint *pPts);
  460. void miDrawLines (miPaintedSet *paintedSet, const miGC *pGC,
  461. miCoordMode mode, int npts, const miPoint *pPts);
  462. void miFillPolygon (miPaintedSet *paintedSet, const miGC *pGC,
  463. miPolygonShape shape,
  464. miCoordMode mode, int npts, const miPoint *pPts);
  465. @end example
  466. @noindent
  467. The final three arguments of each are a coordinate mode, a specified
  468. number of points, and an array that contains that number of points.
  469. @code{miDrawPoints} draws the array as a cloud of points,
  470. @code{miDrawLines} draws a polyline defined by the array, and
  471. @code{miFillPolygon} fills a polygon defined by the array. The
  472. @code{mode} argument specifies whether the points in the array, after
  473. the first, are in absolute or relative coordinates. Its possible values
  474. are:
  475. @example
  476. typedef enum @{ MI_COORD_MODE_ORIGIN,
  477. MI_COORD_MODE_PREVIOUS @} miCoordMode;
  478. @end example
  479. @noindent
  480. The @code{miPoint} structure is defined by
  481. @example
  482. typedef struct
  483. @{
  484. int x, y; /* integer coordinates, y goes downward */
  485. @} miPoint;
  486. @end example
  487. @noindent
  488. The additional @code{shape} argument of @code{miFillPolygon} is
  489. advisory. Its possible values are:
  490. @example
  491. typedef enum @{ MI_SHAPE_GENERAL, MI_SHAPE_CONVEX @} miPolygonShape;
  492. @end example
  493. @noindent
  494. They indicate whether the polygon is (1) unconstrained (i.e., not
  495. necessarily convex, with self-intersections allowed), or @w{(2) convex}
  496. and not self-intersecting. The latter case can be drawn more rapidly.
  497. The rectangle group includes
  498. @example
  499. void miDrawRectangles (miPaintedSet *paintedSet, const miGC *pGC,
  500. int nrects, const miRectangle *pRects);
  501. void miFillRectangles (miPaintedSet *paintedSet, const miGC *pGC,
  502. int nrects, const miRectangle *pRects);
  503. @end example
  504. @noindent
  505. The final two arguments of each are a specified number of rectangles and
  506. an array that contains that number of rectangles.
  507. @code{miDrawRectangles} draws the outline of each rectangle, and
  508. @code{miFillRectangle} fills each rectangle. The @code{miRectangle}
  509. structure is defined by
  510. @example
  511. typedef struct
  512. @{
  513. int x, y; /* upper left corner of rectangle */
  514. unsigned int width, height; /* dimensions: width>=1, height>=1 */
  515. @} miRectangle;
  516. @end example
  517. @noindent
  518. The rectangle group is redundant, since a rectangle is a special sort of
  519. polyline, defined by a five-point point array in which the last point is
  520. the same as the first.
  521. The arc group includes
  522. @example
  523. void miDrawArcs (miPaintedSet *paintedSet, const miGC *pGC,
  524. int narcs, const miArc *parcs);
  525. void miFillArcs (miPaintedSet *paintedSet, const miGC *pGC,
  526. int narcs, const miArc *parcs);
  527. @end example
  528. @noindent
  529. The final two arguments of each are a specified number of arcs and an
  530. array that contains that number of arcs. @code{miDrawArcs} draws each
  531. arc. @w{It will} join successive arcs, if they are contiguous,
  532. according to the `join mode' in the graphics context. Similarly,
  533. @code{miFillArcs} will fill each arc according to the `arc mode' in the
  534. graphics context. Either a pie slice or a chord will be filled.
  535. The @code{miArc} structure is defined by
  536. @example
  537. typedef struct
  538. @{
  539. int x, y; /* upper left corner of ellipse's bounding box */
  540. unsigned int width, height; /* dimensions: width>=1, height>=1 */
  541. int angle1, angle2; /* initial angle, angle range (in 1/64 degrees) */
  542. @} miArc;
  543. @end example
  544. @noindent
  545. @code{x}, @code{y}, @code{width}, @code{height} specify a rectangle
  546. aligned with the coordinate axes, and @code{angle1}, @code{angle2}
  547. specify an angular range (a `pie slice') of an ellipse inscribed in the
  548. rectangle. By convention, they are the starting polar angle and angle
  549. range of the circular arc that would be produced from the elliptic arc
  550. by squeezing the rectangle into a square.
  551. @code{miDrawArcs} maintains a cache of rasterized ellipses. This cache
  552. is persistent, and internal to @code{libxmi}; accordingly,
  553. @code{miDrawArcs} is not reentrant. For applications in which
  554. reentrancy is important, a reentrant counterpart is provided. @w{It is}
  555. @example
  556. void miDrawArcs_r (miPaintedSet *paintedSet, const miGC *pGC,
  557. int narcs, const miArc *parcs,
  558. miEllipseCache *ellipseCache);
  559. @end example
  560. @noindent
  561. The caller of @code{miDrawArcs_r} must supply a pointer to a
  562. @code{miEllipseCache} object as the final argument. @w{A pointer} to
  563. such an object, which is opaque, is returned by
  564. @code{miNewEllipseCache}. After zero or more calls to
  565. @code{miDrawArcs_r}, the object would be deleted by a call to
  566. @code{miDeleteEllipseCache}. The declarations
  567. @example
  568. @group
  569. miEllipseCache * miNewEllipseCache (void);
  570. void miDeleteEllipseCache (miEllipseCache *ellipseCache);
  571. @end group
  572. @end example
  573. @noindent
  574. are supplied in the header file @file{xmi.h}.
  575. @node Second Stage, , First Stage, libxmi API
  576. @subsection The second stage of the graphics pipeline
  577. In the second state of the graphics pipeline, the pixels in a
  578. @code{miPaintedSet} are transferred (`merged') to a @code{miCanvas}, by
  579. invoking @code{miCopyPaintedSetToCanvas}. @w{It is} only when the
  580. painted pixels are transferred to a @code{miCanvas} that clipping to a
  581. pixmap takes place.
  582. @w{A @code{miCanvas}} is a structure that includes a pixmap and several
  583. parameters that control the transfer of pixels. Since it is not opaque,
  584. it may be constructed and modified @w{by hand}, if necessary. The
  585. @code{miCanvas} type has definition
  586. @example
  587. typedef struct
  588. @{
  589. miCanvasPixmap *drawable; /* the pixmap */
  590. @group
  591. miBitmap *stipple; /* a mask, if non-NULL */
  592. miPoint stippleOrigin; /* placement of upper left corner */
  593. @end group
  594. @group
  595. miPixmap *texture; /* a texture, if non-NULL */
  596. miPoint textureOrigin; /* placement of upper left corner */
  597. @end group
  598. @group
  599. miPixelMerge2 pixelMerge2; /* binary merging function, if non-NULL */
  600. miPixelMerge3 pixelMerge3; /* ternary counterpart, if non-NULL */
  601. @end group
  602. @} miCanvas;
  603. @end example
  604. @noindent
  605. Here, the @code{miBitmap} and @code{miPixmap} types are defined by
  606. @example
  607. typedef struct
  608. @{
  609. int **bitmap; /* each element is 0 or 1 */
  610. unsigned int width;
  611. unsigned int height;
  612. @}
  613. miBitmap;
  614. @end example
  615. @example
  616. typedef struct
  617. @{
  618. miPixel **pixmap; /* each element is a miPixel */
  619. unsigned int width;
  620. unsigned int height;
  621. @}
  622. miPixmap;
  623. @end example
  624. @noindent
  625. That is, each of them contains an array of pointers to rows (@w{of
  626. integers} or pixel values, as the case @w{may be}). @w{In most}
  627. installations of @code{libxmi}, @code{miCanvasPixmap} is typedef'd as
  628. @code{miPixmap}. The typedefs
  629. @example
  630. @group
  631. typedef miPixel (*miPixelMerge2) (miPixel source, miPixel destination);
  632. typedef miPixel (*miPixelMerge3) (miPixel texture, miPixel source,
  633. miPixel destination);
  634. @end group
  635. @end example
  636. @noindent
  637. define the datatypes of the binary and ternary pixel-merging function
  638. members.
  639. The functions
  640. @example
  641. @group
  642. miCanvas * miNewCanvas (unsigned int width, unsigned int height,
  643. miPixel initPixel);
  644. void miDeleteCanvas (miCanvas *pCanvas);
  645. miCanvas * miCopyCanvas (const miCanvas *pCanvas);
  646. @end group
  647. @end example
  648. @noindent
  649. are the constructor, destructor, and copy constructor for the
  650. @code{miCanvas} type. Rather than a @code{miCanvas} being created @w{by
  651. hand}, @code{miNewCanvas} is usually used instead. The @code{initPixel}
  652. argument is a @code{miPixel} value with which the newly allocated pixmap
  653. should be filled. The @code{stipple} and @code{texture} pointers in a
  654. newly created @code{miCanvas} are @code{NULL}, as are the pixel-merging
  655. function members. The four convenience functions
  656. @example
  657. @group
  658. void miSetCanvasStipple (miCanvas *pCanvas, const miBitmap *pStipple,
  659. miPoint stippleOrigin);
  660. void miSetCanvasTexture (miCanvas *pCanvas, const miPixmap *pTexture,
  661. miPoint textureOrigin);
  662. @end group
  663. @group
  664. void miSetPixelMerge2 (miCanvas *pCanvas, miPixelMerge2 pixelMerge2);
  665. void miSetPixelMerge3 (miCanvas *pCanvas, miPixelMerge3 pixelMerge3);
  666. @end group
  667. @end example
  668. @noindent
  669. may be used to set these members.
  670. The @code{miCopyPaintedSetToCanvas} function, which implements the
  671. second stage of the graphics pipeline, can now be discussed. @w{It has}
  672. declaration
  673. @example
  674. void miCopyPaintedSetToCanvas (const miPaintedSet *paintedSet,
  675. miCanvas *canvas, miPoint origin);
  676. @end example
  677. @noindent
  678. where @code{origin} is the point on the @code{miCanvas} to which the
  679. point @code{(0,0)} in the @code{miPaintedSet} is mapped. (@w{It could}
  680. equally well be called @code{offset}.)
  681. The semantics of @code{miCopyPaintedSet} boil down to a single issue:
  682. how a `source' pixel in a @code{miPaintedSet} is merged onto the
  683. corresponding `destination' pixel in a @code{miCanvas} to form a new
  684. pixel. The simplest case is when no texture is specified (the
  685. corresponding pointer in the @code{miCanvas} is @code{NULL})@. @w{In
  686. that} case, if the binary pixel-merging function member of the
  687. @code{miCanvas} is @code{NULL}, a default merging algorithm will be
  688. used. @w{In most} @code{libxmi} installations this is the Painter's
  689. Algorithm: the new pixel in the @code{miCanvas} will simply be the
  690. source pixel. @w{If, on} the other hand, the binary pixel-merging
  691. function in the @code{miCanvas} is non-@code{NULL}, @w{it will} be used
  692. to compute the new pixel.
  693. A texture pixmap may be specified. If so, it will be extended
  694. periodically so as to cover the @code{miCanvas}, and its value at the
  695. location of the destination pixel will affect the merging process.
  696. @w{If the} ternary pixel-merging function member of the @code{miCanvas}
  697. is @code{NULL}, a default merging algorithm, appropriate to the case
  698. when a texture is present, will be used. @w{In most} @code{libxmi}
  699. installations this is a variant of the Painter's Algorithm: the new
  700. pixel in the @code{miCanvas} will be the texture pixel, rather than the
  701. source pixel. @w{If, on} the other hand, the ternary pixel-merging
  702. function in the @code{miCanvas} is non-@code{NULL}, @w{it will} be used
  703. to compute the new pixel.
  704. Any @code{miCanvas} may also include a pointer to a stipple bitmap.
  705. @w{If so}, it will be extended periodically so as to cover the
  706. @code{miCanvas}, and its value at the location of the destination pixel
  707. will determine whether or not its replacement by a new pixel, according
  708. to one of the preceding rules, will take place. @w{If the} stipple
  709. value is zero, @w{it will} not; otherwise it will. Stipple bitmaps are
  710. useful for creating so-called screen door patterns, and more generally
  711. for protecting, or @w{masking off}, part of a @code{miCanvas}.
  712. @node Acknowledgements, , libxmi API, Top
  713. @unnumbered Acknowledgements
  714. @code{libxmi} is based on the machine-independent 2-D graphics routines
  715. in the X11 sample server code. Those routines fill polygons and draw
  716. wide polygonal lines and arcs. They were written by Brian Kelleher,
  717. Joel McCormack, Todd Newman, Keith Packard, Robert Scheifler and Ken
  718. Whaley, who worked for Digital Equipment Corp., MIT, and/or the @w{X
  719. Consortium}, and are copyright @copyright{} 1985--89 by the @w{X
  720. Consortium}.
  721. In 1998--99, @email{rsm@@math.arizona.edu, Robert Maier} extracted the
  722. graphics routines from the sample server code in the X11R6 distribution,
  723. converted them to @w{ANSI C}, and added extensive comments. @w{He also}
  724. introduced data structures appropriate for a two-stage graphics
  725. pipeline, and converted the graphics routines to use them. @w{He added}
  726. some new rendering features, such as support for multicolored dashing.
  727. The modified code was first released by being incorporated in version
  728. 2.2 of the GNU @code{plotutils} package, as a rendering module for
  729. export of PNM and pseudo-GIF files. See the
  730. @uref{http://www.gnu.org/software/plotutils/plotutils.html,
  731. @code{plotutils} home page}. After further modifications, the code was
  732. released as the standalone @code{libxmi} library.
  733. @bye