1 /* output-cgm.c: CGM output
2
3 Copyright (C) 1999, 2000, 2001 Martin Weber.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License
7 as published by the Free Software Foundation; either version 2.1 of
8 the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 USA. */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif /* Def: HAVE_CONFIG_H */
23
24 #include "types.h"
25 #include "spline.h"
26 #include "color.h"
27 #include "output-cgm.h"
28 #include "xstd.h"
29 #include "autotrace.h"
30 #include <string.h>
31
32 #define CGM_BEGINMETAFILE 0x0020
33 #define CGM_BEGINPICTURE 0x0060
34 #define CGM_METAFILEVERSION 0x1022
35 #define CGM_METAFILEDESCRIPTION 0x1040
36
37 typedef unsigned short int UI16;
38 typedef unsigned char UI8;
39
40 /* endianess independent IO functions */
41
write16(FILE * fdes,UI16 data)42 static at_bool write16(FILE *fdes, UI16 data)
43 {
44 size_t count = 0;
45 UI8 outch;
46
47 outch = (UI8) ((data >> 8) & 0x0FF);
48 count += fwrite(&outch, 1, 1, fdes);
49
50 outch = (UI8) (data & 0x0FF);
51 count += fwrite(&outch, 1, 1, fdes);
52
53 return (count == sizeof(UI16)) ? true : false;
54 }
55
write8(FILE * fdes,UI8 data)56 static at_bool write8(FILE *fdes, UI8 data)
57 {
58 size_t count = 0;
59
60 count = fwrite(&data, 1, 1, fdes);
61
62 return (count == sizeof(UI8)) ? true : false;
63 }
64
65
output_beginmetafilename(FILE * fdes,const char * string)66 static at_bool output_beginmetafilename(FILE *fdes, const char *string)
67 {
68 int len = strlen (string);
69
70 if (len + 1 < 0x001F)
71 write16(fdes, CGM_BEGINMETAFILE + len + 1);
72 else
73 {
74 write16(fdes, CGM_BEGINMETAFILE + 0x001F);
75 write16(fdes, len + 1);
76 }
77
78 write8(fdes, len);
79
80 while (*string != '\0')
81 {
82 write8(fdes, *string);
83 string++;
84 }
85
86 if (len % 2 == 0)
87 write8(fdes, 0);
88
89
90 return true;
91 }
92
output_beginpicture(FILE * fdes,const char * string)93 static at_bool output_beginpicture(FILE *fdes, const char *string)
94 {
95 int len = strlen (string);
96
97 if (len + 1 < 0x001F)
98 write16(fdes, CGM_BEGINPICTURE + len + 1);
99 else
100 {
101 write16(fdes, CGM_BEGINPICTURE + 0x001F);
102 write16(fdes, len + 1);
103 }
104
105 write8(fdes, len);
106
107 while (*string != '\0')
108 {
109 write8(fdes, *string);
110 string++;
111 }
112
113 if (len % 2 == 0)
114 write8(fdes, 0);
115
116
117 return true;
118 }
119
output_metafiledescription(FILE * fdes,const char * string)120 static at_bool output_metafiledescription(FILE *fdes, const char *string)
121 {
122 int len = strlen (string);
123
124 if (len + 1 < 0x001F)
125 write16(fdes, CGM_METAFILEDESCRIPTION + len + 1);
126 else
127 {
128 write16(fdes, CGM_METAFILEDESCRIPTION + 0x001F);
129 write16(fdes, len + 1);
130 }
131
132 write8(fdes, len);
133
134 while (*string != '\0')
135 {
136 write8(fdes, *string);
137 string++;
138 }
139
140 if (len % 2 == 0)
141 write8(fdes, 0);
142
143
144 return true;
145 }
146
output_cgm_writer(FILE * cgm_file,at_string name,int llx,int lly,int urx,int ury,at_output_opts_type * opts,spline_list_array_type shape,at_msg_func msg_func,at_address msg_data)147 int output_cgm_writer(FILE* cgm_file, at_string name,
148 int llx, int lly, int urx, int ury,
149 at_output_opts_type * opts,
150 spline_list_array_type shape,
151 at_msg_func msg_func,
152 at_address msg_data)
153 {
154 unsigned this_list;
155 char *des;
156 const char * version_string = at_version(true);
157
158 output_beginmetafilename (cgm_file, name);
159
160 write16 (cgm_file, CGM_METAFILEVERSION);
161 write16 (cgm_file, 0x0002);
162
163 des = (char *) malloc (strlen ("created by ") + strlen (version_string) + 1);
164 strcpy (des, "created by ");
165 strcat (des, version_string);
166 output_metafiledescription (cgm_file, des);
167 free (des);
168
169 write16 (cgm_file, 0x1166); /* metafile element list */
170 write16 (cgm_file, 0x0001);
171 write16 (cgm_file, 0xFFFF);
172 write16 (cgm_file, 0x0001);
173
174 output_beginpicture(cgm_file, "pic1");
175
176 write16 (cgm_file, 0x2042);/* color selection modes (1 = direct) */
177 write16 (cgm_file, 0x0001);
178
179 write16 (cgm_file, 0x20C8);/* vdc extend */
180 write16 (cgm_file, llx/*0x0000*/);
181 write16 (cgm_file, urx/*0x7FFF*/);
182 write16 (cgm_file, ury/*0x7FFF*/);
183 write16 (cgm_file, lly/*0x0000*/);
184
185 write16 (cgm_file, 0x0080);/* begin picture body */
186
187
188 for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape);
189 this_list++)
190 {
191 unsigned this_spline;
192
193 spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
194
195 if (this_list > 0)
196 {
197 if (shape.centerline)
198 write16 (cgm_file, 0x0200); /* end a compound line */
199 else
200 write16 (cgm_file, 0x0120); /* end a figure */
201 }
202
203 if (shape.centerline)
204 write16 (cgm_file, 0x5083);/* line */
205 else
206 write16 (cgm_file, 0x52E3);/* fill */;
207
208 /* color output */
209 if (list.clockwise && shape.background_color != NULL)
210 {
211 write8 (cgm_file, shape.background_color->r);
212 write8 (cgm_file, shape.background_color->g);
213 write8 (cgm_file, shape.background_color->b);
214 }
215 else
216 {
217 write8 (cgm_file, list.color.r);
218 write8 (cgm_file, list.color.g);
219 write8 (cgm_file, list.color.b);
220 }
221 write8 (cgm_file, 0);
222
223 if (shape.centerline)
224 {
225 write16 (cgm_file, 0x53C2);/* edge visibility on */
226 write16 (cgm_file, 0x0001);
227 }
228 else
229 {
230 write16 (cgm_file, 0x52C2);/* interior style solid */
231 write16 (cgm_file, 0x0001);
232 }
233
234 if (shape.centerline)
235 write16 (cgm_file, 0x01E0); /* begin a compound line */
236 else
237 write16 (cgm_file, 0x0100); /* begin a figure */
238
239 for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list);
240 this_spline++)
241 {
242 spline_type s = SPLINE_LIST_ELT (list, this_spline);
243
244 if (SPLINE_DEGREE (s) == LINEARTYPE)
245 {
246 write16 (cgm_file, 0x4028); /* polyline */
247 write16 (cgm_file, (UI16) START_POINT (s).x);
248 write16 (cgm_file, ury - (UI16) START_POINT (s).y);
249 write16 (cgm_file, (UI16) END_POINT (s).x);
250 write16 (cgm_file, ury - (UI16) END_POINT (s).y);
251 }
252 else
253 {
254 write16 (cgm_file, 0x4352); /* polybezier */
255 write16 (cgm_file, 0x0002); /* continuous */
256 write16 (cgm_file, (UI16) START_POINT (s).x);
257 write16 (cgm_file, ury - (UI16) START_POINT (s).y);
258 write16 (cgm_file, (UI16) CONTROL1 (s).x);
259 write16 (cgm_file, ury - (UI16) CONTROL1 (s).y);
260 write16 (cgm_file, (UI16) CONTROL2 (s).x);
261 write16 (cgm_file, ury - (UI16) CONTROL2 (s).y);
262 write16 (cgm_file, (UI16) END_POINT (s).x);
263 write16 (cgm_file, ury - (UI16) END_POINT (s).y);
264 }
265 }
266 }
267
268 if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0)
269 {
270 if (shape.centerline)
271 write16 (cgm_file, 0x0200); /* end a compound line */
272 else
273 write16 (cgm_file, 0x0120); /* end a figure */
274 }
275
276 write16 (cgm_file, 0x00A0); /* end picture */
277
278 write16 (cgm_file, 0x0040); /* end metafile */
279
280 return(0);
281
282 }
283
284
285