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