1 /* output-er.c: utility routines for Elastic Reality shape file 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 "output-er.h"
27 #include "xstd.h"
28 #include <time.h>
29 #include <string.h>
30 
31 static at_string now(void);
32 
33 #define NUM_CORRESP_POINTS 4
34 
35 /* This should be called before the others in this file.  It opens the
36    output file and writes some preliminary boilerplate. */
37 
38 static int
output_er_header(FILE * er_file,at_string name,int llx,int lly,int urx,int ury)39 output_er_header(FILE* er_file, at_string name, int llx, int lly, int urx, int ury)
40 {
41     at_string time;
42 
43     fprintf(er_file, "#Elastic Reality Shape File\n\n#Date: %s\n\n",
44         time = now());
45 
46     free(time);
47 
48     fprintf(er_file, "ImageSize = {\n\tWidth = %d\n\tHeight = %d\n}\n\n",
49 	urx - llx, ury - lly);
50 
51     return 0;
52 }
53 
54 /* This outputs shape data and the point list for the shape in SHAPE. */
55 
56 static void
out_splines(FILE * er_file,spline_list_array_type shape,unsigned width,unsigned height,at_output_opts_type * opts)57 out_splines(FILE* er_file, spline_list_array_type shape,
58 	    unsigned width, unsigned height,
59 	    at_output_opts_type * opts)
60 {
61     unsigned this_list, corresp_pt;
62     double x0, y0, x1, y1, x2, y2, corresp_length;
63 
64     for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape);
65         this_list++)
66     {
67         unsigned this_spline;
68         spline_type prev;
69 
70         spline_list_type list = SPLINE_LIST_ARRAY_ELT(shape, this_list);
71         unsigned length = SPLINE_LIST_LENGTH(list);
72         unsigned out_length = (list.open || length == 1 ? length + 1 : length);
73 
74         fprintf(er_file, "Shape = {\n");
75         fprintf(er_file, "\t#Shape Number %d\n", this_list + 1);
76         fprintf(er_file, "\tGroup = Default\n");
77         fprintf(er_file, "\tType = Source\n");
78         fprintf(er_file, "\tRoll = A\n");
79         fprintf(er_file, "\tOpaque = True\n");
80         fprintf(er_file, "\tLocked = False\n");
81         fprintf(er_file, "\tWarp = True\n");
82         fprintf(er_file, "\tCookieCut = True\n");
83         fprintf(er_file, "\tColorCorrect = True\n");
84         fprintf(er_file, "\tPrecision = 10\n");
85         fprintf(er_file, "\tClosed = %s\n", (list.open ? "False" : "True"));
86         fprintf(er_file, "\tTween = Linear\n");
87         fprintf(er_file, "\tBPoints = %d\n", out_length);
88         fprintf(er_file, "\tCPoints = %d\n", NUM_CORRESP_POINTS);
89         fprintf(er_file, "\tFormKey = {\n");
90         fprintf(er_file, "\t\tFrame = 1\n");
91         fprintf(er_file, "\t\tPointList = {\n");
92 
93         prev = PREV_SPLINE_LIST_ELT(list, 0);
94         if (list.open || length == 1)
95             SPLINE_DEGREE(prev) = (polynomial_degree) -1;
96 
97         for (this_spline = 0; this_spline < length; this_spline++)
98         {
99             spline_type s = SPLINE_LIST_ELT(list, this_spline);
100 
101             if (SPLINE_DEGREE(prev) == -1)
102                 { x0 = START_POINT(s).x; y0 = START_POINT(s).y; }
103             else if (SPLINE_DEGREE(prev) == CUBICTYPE)
104                 { x0 = CONTROL2(prev).x; y0 = CONTROL2(prev).y; }
105             else /* if (SPLINE_DEGREE(prev) == LINEARTYPE) */
106                 { x0 = START_POINT(s).x; y0 = START_POINT(s).y; }
107 
108             x1 = START_POINT(s).x; y1 = START_POINT(s).y;
109 
110             if (SPLINE_DEGREE(s) == CUBICTYPE)
111                 { x2 = CONTROL1(s).x; y2 = CONTROL1(s).y; }
112             else
113                 { x2 = START_POINT(s).x; y2 = START_POINT(s).y; }
114 
115             fprintf(er_file, "\t\t\t(%f, %f), (%f, %f), (%f, %f),\n",
116                 x0 / width, y0 / height, x1 / width, y1 / height,
117                 x2 / width, y2 / height);
118 
119             prev = s;
120         }
121 
122         if (list.open || length == 1)
123         {
124             x0 = CONTROL2(prev).x; y0 = CONTROL2(prev).y;
125             x2 = x1 = END_POINT(prev).x; y2 = y1 = END_POINT(prev).y;
126 
127             fprintf(er_file, "\t\t\t(%f, %f), (%f, %f), (%f, %f),\n",
128                 x0 / width, y0 / height, x1 / width, y1 / height,
129                 x2 / width, y2 / height);
130         }
131 
132         /* Close PointList and enclosing FormKey. */
133         fprintf(er_file, "\t\t}\n\n\t}\n\n");
134 
135         if (shape.centerline && shape.preserve_width)
136         {
137           at_real w = (at_real) 1.0 / (shape.width_weight_factor);
138 
139           fprintf(er_file, "\tWeightKey = {\n");
140           fprintf(er_file, "\t\tFrame = 1\n");
141           fprintf(er_file, "\t\tPointList = {\n");
142           prev = PREV_SPLINE_LIST_ELT(list, 0);
143           if (list.open || length == 1)
144             SPLINE_DEGREE(prev) = (polynomial_degree) -1;
145           for (this_spline = 0; this_spline < length; this_spline++)
146           {
147       	    spline_type s = SPLINE_LIST_ELT(list, this_spline);
148 
149       	    if (SPLINE_DEGREE(prev) == -1)
150               x0 = START_POINT(s).z;
151             else if (SPLINE_DEGREE(prev) == CUBICTYPE)
152               x0 = CONTROL2(prev).z;
153             else /* if (SPLINE_DEGREE(prev) == LINEARTYPE) */
154               x0 = START_POINT(s).z;
155 
156             x1 = START_POINT(s).z;
157 
158             if (SPLINE_DEGREE(s) == CUBICTYPE)
159 	          x2 = CONTROL1(s).z;
160             else
161               x2 = START_POINT(s).z;
162 
163             fprintf(er_file, "\t\t\t%g, %g, %g,\n", x0*w, x1*w, x2*w);
164 
165             prev = s;
166           }
167           if (list.open || length == 1)
168           {
169             x0 = CONTROL2(prev).z;
170             x2 = x1 = END_POINT(prev).z;
171             fprintf(er_file, "\t\t\t%g, %g, %g,\n", x0*w, x1*w, x2*w);
172           }
173           /* Close PointList and enclosing WeightKey. */
174           fprintf(er_file, "\t\t}\n\n\t}\n\n");
175         }
176 
177         fprintf(er_file, "\tCorrKey = {\n");
178         fprintf(er_file, "\t\tFrame = 1\n");
179         fprintf(er_file, "\t\tPointList = {\n");
180         fprintf(er_file, "\t\t\t0");
181         corresp_length = out_length - (list.open ? 1.0 : 2.0);
182         for (corresp_pt = 1; corresp_pt < NUM_CORRESP_POINTS; corresp_pt++)
183         {
184             fprintf(er_file, ", %g", corresp_length * corresp_pt
185               / (NUM_CORRESP_POINTS - (list.open ? 1.0 : 0.0)));
186         }
187         /* Close PointList and enclosing CorrKey. */
188         fprintf(er_file, "\n\t\t}\n\n\t}\n\n");
189 
190         /* Close Shape. */
191         fprintf(er_file, "}\n\n");
192     }
193 }
194 
195 int
output_er_writer(FILE * 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)196 output_er_writer(FILE* file, at_string name, int llx, int lly, int urx, int ury,
197 		 at_output_opts_type * opts,
198 		 spline_list_array_type shape,
199 		 at_msg_func msg_func,
200 		 at_address msg_data)
201 {
202     int result;
203     unsigned width, height;
204 
205     result = output_er_header(file, name, llx, lly, urx, ury);
206     if (result != 0) return result;
207 
208     width = urx - llx;
209     height = ury - lly;
210     out_splines(file, shape, width, height, opts);
211 
212     return 0;
213 }
214 
215 static at_string
now(void)216 now(void)
217 {
218     at_string time_string;
219     time_t t = time (0);
220 
221     XMALLOC (time_string, 26);  /* not 25 ! */
222     strcpy (time_string, ctime (&t));
223     time_string[24] = 0;  /* No newline. */
224 
225     return time_string;
226 }
227 
228