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