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