drawing.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* This is a sample program that uses libxmi to draw on a 60x35 canvas, and
  2. writes the canvas to standard output. Actually, since libxmi uses a
  3. two-stage graphics pipeline, the program first constructs a `painted
  4. set' (a set of points with integer coordinates, partitioned by pixel
  5. value), and merges the painted set onto a 60x35 canvas.
  6. The painted set consists of a filled rectangle, a polyline, and an arc
  7. that subtends 270 degrees. The rectangle is filled with color 1. The
  8. polyline and the arc are dashed. Their line type is
  9. MI_LINE_ON_OFF_DASHED, and the `on' dashes are multicolored: they cycle
  10. through colors 1,2,3. (The `off' dashes are not drawn, but if they were
  11. [which would be the case if MI_LINE_DOUBLE_DASHED were the line type],
  12. they would all be in color 0.) The background color of the canvas onto
  13. which the painted set is merged is 0.
  14. All these color values are miPixel values, and may be chosen
  15. arbitrarily. By default, miPixel is typedef'd to `unsigned int'. You
  16. may interpret a miPixel however you choose. It could be a color index,
  17. an RGB value,...
  18. The line width for both the polyline and the arc is set to `0'. This is
  19. a special value: it requests that a so-called Bresenham algorithm be
  20. used. A Bresenham algorithm often yields better-looking lines than line
  21. width 1. If the line width is positive, the polyline and the arc will
  22. be drawn with a brush of that width, and all pixels touched by the brush
  23. will be painted. Dashing may be requested for positive line width, just
  24. as it is for line width 0. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <xmi.h> /* public libxmi header file */
  28. int main ()
  29. {
  30. miRectangle rect; /* 1 rectangle to be filled */
  31. miPoint points[4]; /* 3 line segments in polyline to be drawn */
  32. miArc arc; /* 1 arc to be drawn */
  33. miPixel pixels[4]; /* pixel values for drawing and dashing */
  34. unsigned int dashes[2]; /* length of `on' and `off' dashes */
  35. miGC *pGC; /* graphics context */
  36. miPaintedSet *paintedSet; /* opaque object to be painted */
  37. miCanvas *canvas; /* drawing canvas (including pixmap) */
  38. miPoint offset; /* for miPaintedSet -> miCanvas transfer */
  39. int i, j;
  40. /* Define rectangle: upper left vertex = (40,0), lower right = (55,5). */
  41. /* But note libxmi's convention: right and bottom edges of filled
  42. polygons (including rectangles) are never painted, in order that
  43. adjacent polygons will abut with no overlaps or gaps. This filled
  44. rectangle, when merged onto the canvas, will extend only to (54,4). */
  45. rect.x = 40; rect.y = 0;
  46. rect.width = 15; rect.height = 5;
  47. /* define polyline: vertices are (25,5) (5,5), (5,25), (35,22) */
  48. points[0].x = 25; points[0].y = 5;
  49. points[1].x = 5; points[1].y = 5;
  50. points[2].x = 5; points[2].y = 25;
  51. points[3].x = 35; points[3].y = 22;
  52. /* define elliptic arc */
  53. arc.x = 20; arc.y = 15; /* upper left corner of bounding box */
  54. arc.width = 30; /* x range of box: 20..50 */
  55. arc.height = 16; /* y range of box: 15..31 */
  56. arc.angle1 = 0 * 64; /* starting angle (1/64'ths of a degree) */
  57. arc.angle2 = 270 * 64; /* angle range (1/64'ths of a degree) */
  58. /* create and modify graphics context */
  59. pixels[0] = 0; /* pixel value for `off' dashes, if drawn */
  60. pixels[1] = 1; /* default pixel for drawing */
  61. pixels[2] = 2; /* another pixel, for multicolored dashes */
  62. pixels[3] = 3; /* another pixel, for multicolored dashes */
  63. dashes[0] = 4; /* length of `on' dashes */
  64. dashes[1] = 2; /* length of `off' dashes */
  65. pGC = miNewGC (4, pixels);
  66. miSetGCAttrib (pGC, MI_GC_LINE_STYLE, MI_LINE_ON_OFF_DASH);
  67. miSetGCDashes (pGC, 2, dashes, 0);
  68. miSetGCAttrib (pGC, MI_GC_LINE_WIDTH, 0); /* Bresenham algorithm */
  69. /* create empty painted set */
  70. paintedSet = miNewPaintedSet ();
  71. /* Paint filled rectangle, dashed polyline and dashed arc onto painted
  72. set. Rectangle will be filled with the default pixel value for
  73. drawing, i.e., pixels[1], i.e., 2, and polyline and arc will be drawn
  74. rather than filled: they will be dashed as specified above. */
  75. miFillRectangles (paintedSet, pGC, 1, &rect);
  76. miDrawLines (paintedSet, pGC, MI_COORD_MODE_ORIGIN, 4, points);
  77. miDrawArcs (paintedSet, pGC, 1, &arc);
  78. /* create 60x35 canvas (initPixel=0); merge painted set onto it */
  79. canvas = miNewCanvas (60, 35, 0);
  80. offset.x = 0; offset.y = 0;
  81. miCopyPaintedSetToCanvas (paintedSet, canvas, offset);
  82. /* write canvas's pixmap (a 60x35 array of miPixels) to stdout */
  83. for (j = 0; j < canvas->drawable->height; j++)
  84. {
  85. for (i = 0; i < canvas->drawable->width; i++)
  86. /* note: column index precedes row index */
  87. printf ("%d", canvas->drawable->pixmap[j][i]);
  88. printf ("\n");
  89. }
  90. /* clean up */
  91. miDeleteCanvas (canvas);
  92. miDeleteGC (pGC);
  93. miClearPaintedSet (paintedSet); /* not necessary */
  94. miDeletePaintedSet (paintedSet);
  95. return 0;
  96. }