mi_gc.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* This file is part of the GNU libxmi package. Copyright (C) 1998, 1999,
  2. 2000, 2005, Free Software Foundation, Inc.
  3. The GNU libxmi package is free software. You may redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software foundation; either version 2, or (at your
  6. option) any later version.
  7. The GNU libxmi package is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with the GNU plotutils package; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  14. Boston, MA 02110-1301, USA. */
  15. #include "sys-defines.h"
  16. #include "extern.h"
  17. /* These functions create, manipulate and destroy miGC structures. A
  18. pointer to an miGC is passed as the third argument to each of libxmi's
  19. public drawing functions. It comprises high-level drawing parameters.
  20. The miGC structure is defined in mi_gc.h. */
  21. #include "xmi.h"
  22. #include "mi_spans.h"
  23. #include "mi_gc.h"
  24. #include "mi_api.h"
  25. /* create a new miGC, with elements initialized to default values (the same
  26. default values that are used by X11) */
  27. miGC *
  28. miNewGC (int npixels, const miPixel *pixels)
  29. {
  30. miGC *new_gc;
  31. int i;
  32. new_gc = (miGC *)mi_xmalloc (sizeof (miGC));
  33. new_gc->fillRule = MI_EVEN_ODD_RULE;
  34. new_gc->joinStyle = MI_JOIN_MITER;
  35. new_gc->capStyle = MI_CAP_BUTT;
  36. new_gc->lineStyle = MI_LINE_SOLID;
  37. new_gc->arcMode = MI_ARC_PIE_SLICE;
  38. new_gc->lineWidth = (unsigned int)0;
  39. new_gc->miterLimit = 10.43; /* same as hardcoded in X11 */
  40. new_gc->dashOffset = 0;
  41. new_gc->numInDashList = 2;
  42. new_gc->dash = (unsigned int *)mi_xmalloc (2 * sizeof(unsigned int));
  43. for (i = 0; i < 2; i++)
  44. new_gc->dash[i] = 4; /* { 4, 4 }; same as in X11? */
  45. new_gc->numPixels = npixels;
  46. new_gc->pixels = (miPixel *)mi_xmalloc (npixels * sizeof (miPixel));
  47. for (i = 0; i < npixels; i++)
  48. new_gc->pixels[i] = pixels[i];
  49. return new_gc;
  50. }
  51. /* destroy (deallocate) an miGC */
  52. void
  53. miDeleteGC (miGC *pGC)
  54. {
  55. if (pGC == (miGC *)NULL)
  56. return;
  57. if (pGC->dash)
  58. free (pGC->dash);
  59. free (pGC->pixels);
  60. free (pGC);
  61. }
  62. /* copy an miGC */
  63. miGC *
  64. miCopyGC (const miGC *pGC)
  65. {
  66. miGC *new_gc;
  67. int i;
  68. if (pGC == (const miGC *)pGC)
  69. return (miGC *)NULL;
  70. new_gc = (miGC *)mi_xmalloc (sizeof (miGC));
  71. new_gc->fillRule = pGC->fillRule;
  72. new_gc->joinStyle = pGC->joinStyle;
  73. new_gc->capStyle = pGC->capStyle;
  74. new_gc->lineStyle = pGC->lineStyle;
  75. new_gc->arcMode = pGC->arcMode;
  76. new_gc->lineWidth = pGC->lineWidth;
  77. new_gc->miterLimit = pGC->miterLimit;
  78. new_gc->dashOffset = pGC->dashOffset;
  79. new_gc->numInDashList = pGC->numInDashList;
  80. if (pGC->numInDashList == 0)
  81. new_gc->dash = (unsigned int *)NULL;
  82. else
  83. {
  84. new_gc->dash =
  85. (unsigned int *)mi_xmalloc (pGC->numInDashList * sizeof(unsigned int));
  86. for (i = 0; i < pGC->numInDashList; i++)
  87. new_gc->dash[i] = pGC->dash[i];
  88. }
  89. new_gc->pixels =
  90. (miPixel *)mi_xmalloc (pGC->numPixels * sizeof(miPixel));
  91. for (i = 0; i < pGC->numPixels; i++)
  92. new_gc->pixels[i] = pGC->pixels[i];
  93. return new_gc;
  94. }
  95. /* set a single integer-valued miGC attribute */
  96. void
  97. miSetGCAttrib (miGC *pGC, miGCAttribute attribute, int value)
  98. {
  99. if (pGC == (miGC *)NULL || value < 0)
  100. return;
  101. switch ((int)attribute)
  102. {
  103. case (int)MI_GC_FILL_RULE:
  104. pGC->fillRule = value;
  105. break;
  106. case (int)MI_GC_JOIN_STYLE:
  107. pGC->joinStyle = value;
  108. break;
  109. case (int)MI_GC_CAP_STYLE:
  110. pGC->capStyle = value;
  111. break;
  112. case (int)MI_GC_LINE_STYLE:
  113. pGC->lineStyle = value;
  114. break;
  115. case (int)MI_GC_ARC_MODE:
  116. pGC->arcMode = value;
  117. break;
  118. case (int)MI_GC_LINE_WIDTH:
  119. if (value >= 0)
  120. pGC->lineWidth = (unsigned int)value;
  121. break;
  122. default: /* unknown attribute type */
  123. break;
  124. }
  125. }
  126. /* set many integer-valued miGC attributes, at a single time */
  127. void
  128. miSetGCAttribs (miGC *pGC, int nattributes, const miGCAttribute *attributes, const int *values)
  129. {
  130. int i;
  131. miGCAttribute attribute;
  132. int value;
  133. if (nattributes <= 0 || pGC == (miGC *)NULL)
  134. return;
  135. for (i = 0; i < nattributes; i++)
  136. {
  137. attribute = *attributes++;
  138. value = *values++;
  139. if (value < 0) /* invalid; be tolerant */
  140. continue;
  141. switch ((int)attribute)
  142. {
  143. case (int)MI_GC_FILL_RULE:
  144. pGC->fillRule = value;
  145. break;
  146. case (int)MI_GC_JOIN_STYLE:
  147. pGC->joinStyle = value;
  148. break;
  149. case (int)MI_GC_CAP_STYLE:
  150. pGC->capStyle = value;
  151. break;
  152. case (int)MI_GC_LINE_STYLE:
  153. pGC->lineStyle = value;
  154. break;
  155. case (int)MI_GC_ARC_MODE:
  156. pGC->arcMode = value;
  157. break;
  158. case (int)MI_GC_LINE_WIDTH:
  159. if (value >= 0)
  160. pGC->lineWidth = (unsigned int)value;
  161. break;
  162. default: /* unknown attribute type */
  163. break;
  164. }
  165. }
  166. }
  167. /* set the only float-valued miGC attribute (the miter limit) */
  168. void
  169. miSetGCMiterLimit (miGC *pGC, double value)
  170. {
  171. if (pGC == (miGC *)NULL)
  172. return;
  173. pGC->miterLimit = value;
  174. }
  175. /* set the dash-related attributes in an miGC */
  176. void
  177. miSetGCDashes (miGC *pGC, int ndashes, const unsigned int *dashes, int offset)
  178. {
  179. int i;
  180. if (pGC == (miGC *)NULL || ndashes < 0)
  181. return;
  182. if (pGC->dash)
  183. free (pGC->dash);
  184. pGC->dashOffset = offset;
  185. pGC->numInDashList = ndashes;
  186. if (ndashes == 0)
  187. pGC->dash = (unsigned int *)NULL;
  188. else
  189. {
  190. pGC->dash = (unsigned int *)mi_xmalloc (ndashes * sizeof(unsigned int));
  191. for (i = 0; i < ndashes; i++)
  192. pGC->dash[i] = dashes[i];
  193. }
  194. }
  195. /* set the pixel array in a miGC */
  196. void
  197. miSetGCPixels (miGC *pGC, int npixels, const miPixel *pixels)
  198. {
  199. int i;
  200. if (pGC == (miGC *)NULL || npixels < 2)
  201. return;
  202. free (pGC->pixels);
  203. pGC->numPixels = npixels;
  204. pGC->pixels = (miPixel *)mi_xmalloc (npixels * sizeof (miPixel));
  205. for (i = 0; i < npixels; i++)
  206. pGC->pixels[i] = pixels[i];
  207. }