1 /* output-mif.c: utility routines for FrameMaker MIF output
2 
3    Copyright (C) 2001 Per Grahn
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-mif.h"
28 #include "xstd.h"
29 #include "autotrace.h"
30 #include <time.h>
31 #include <math.h>
32 #include <string.h>
33 
34 typedef struct {
35   char *tag;
36   color_type c;
37 } ColorT;
38 
39 typedef struct {
40   int llx;
41   int lly;
42   int urx;
43   int ury;
44   at_real dpi;
45 } BboxT;
46 
47 BboxT cbox;
48 
49 /*===========================================================================
50   Return a color name based on RGB value
51 ===========================================================================*/
colorstring(int r,int g,int b)52 static const char * colorstring(int r, int g, int b)
53 {
54   static char buffer[15];
55   if( r==0 && g==0 && b==0 )
56     return "Black";
57   else if( r==255 && g==0 && b==0 )
58     return "Red";
59   else if( r==0 && g==255 && b==0 )
60     return "Green";
61   else if( r==0 && g==0 && b==255 )
62     return "Blue";
63   else if( r==255 && g==255 && b==0 )
64     return "Yellow";
65   else if( r==255 && g==0 && b==255 )
66     return "Magenta";
67   else if( r==0 && g==255 && b==255 )
68     return "Cyan";
69   else if( r==255 && g==255 && b==255 )
70     return "White";
71   else {
72     sprintf(buffer,"R%.3dG%.3dB%.3d", r, g, b);
73   }
74   return buffer;
75 }
76 
77 /*===========================================================================
78  Convert Bezier Spline
79 ===========================================================================*/
bezpnt(at_real t,at_real z1,at_real z2,at_real z3,at_real z4)80 static at_real bezpnt(at_real t, at_real z1, at_real z2, at_real z3, at_real z4)
81 {
82   at_real temp, t1;
83   /* Determine ordinate on Bezier curve at length "t" on curve */
84   if (t < (at_real) 0.0) { t = (at_real) 0.0; }
85   if (t > (at_real) 1.0) { t = (at_real) 1.0; }
86   t1 = ((at_real) 1.0 - t);
87   temp = t1*t1*t1*z1 + (at_real)3.0*t*t1*t1*z2 + (at_real)3.0*t*t*t1*z3 + t*t*t*z4;
88   return(temp);
89 }
90 
91 /*===========================================================================
92   Print a point
93 ===========================================================================*/
print_coord(FILE * f,at_real x,at_real y)94 static void print_coord(FILE* f, at_real x, at_real y)
95 {
96   fprintf(f, "  <Point %.2f %.2f>\n",
97     x*72.0/cbox.dpi, (cbox.ury-y+1)*72.0/cbox.dpi);
98 }
99 
100 /*===========================================================================
101   Main conversion routine
102 ===========================================================================*/
output_mif_writer(FILE * ps_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)103 int output_mif_writer(FILE* ps_file, at_string name,
104 		      int llx, int lly, int urx, int ury,
105 		      at_output_opts_type * opts,
106 		      spline_list_array_type shape,
107 		      at_msg_func msg_func, at_address msg_data)
108 {
109   unsigned this_list;
110   int i;
111   ColorT col_tbl[256];
112   int n_ctbl = 0;
113   color_type curr_color = {0,0,0};
114 
115 
116   cbox.llx = llx;
117   cbox.lly = lly;
118   cbox.urx = urx;
119   cbox.ury = ury;
120   cbox.dpi = (at_real) opts->dpi;
121 
122   fprintf(ps_file, "<MIFFile 4.00> #%s\n<Units Upt>\n<ColorCatalog\n", at_version(true));
123 
124   for( this_list=0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape); this_list++ ){
125     spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
126     curr_color = (list.clockwise && shape.background_color != NULL)? *(shape.background_color) : list.color;
127 
128     for( i=0; i<n_ctbl; i++ )
129       if( COLOR_EQUAL(curr_color, col_tbl[i].c) ) break;
130 
131     if( i >= n_ctbl ){
132       col_tbl[n_ctbl].tag = strdup(colorstring(curr_color.r, curr_color.g, curr_color.b));
133       col_tbl[n_ctbl].c = curr_color;
134       n_ctbl++;
135     }
136   }
137   for( i=0; i<n_ctbl; i++ ){
138     int c, m, y, k;
139     c = k = 255 - col_tbl[i].c.r;
140     m = 255 - col_tbl[i].c.g;
141     if( m < k ) k = m;
142     y = 255 - col_tbl[i].c.b;
143     if( y < k ) k = y;
144     c -= k;
145     m -= k;
146     y -= k;
147     fprintf(ps_file,
148       " <Color <ColorTag %s><ColorCyan %d><ColorMagenta %d>"
149       "<ColorYellow %d><ColorBlack %d>>\n",
150       col_tbl[i].tag, c*100/255, m*100/255, y*100/255, k*100/255);
151   }
152   fprintf(ps_file, ">\n");
153 
154   fprintf(ps_file, "<Frame\n"
155     " <Pen 15>\n"
156     " <Fill 15>\n"
157     " <PenWidth  0.2 pt>\n"
158     " <Separation 0>\n"
159     " <BRect  0.0 pt 0.0 pt %.1f pt %.1f pt>\n",
160     (urx-llx)*72.0/cbox.dpi, (ury-lly)*72.0/cbox.dpi);
161 
162 
163   for( this_list=0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape); this_list++ ){
164     unsigned this_spline;
165     at_bool smooth;
166 
167     spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
168     spline_type first = SPLINE_LIST_ELT (list, 0);
169 
170     for( i=0; i<n_ctbl; i++ )
171       if( COLOR_EQUAL(curr_color, col_tbl[i].c) ) break;
172 
173     fprintf(ps_file, " %s\n",
174       (shape.centerline || list.open) ?
175       "<PolyLine <Fill 15><Pen 0>" :
176       "<Polygon <Fill 0><Pen 15>");
177     fprintf(ps_file, "  <ObColor `%s'>\n", col_tbl[i].tag);
178 
179     print_coord(ps_file, START_POINT (first).x, START_POINT (first).y);
180     smooth = false;
181     for( this_spline=0; this_spline < SPLINE_LIST_LENGTH(list); this_spline++ ){
182       spline_type s = SPLINE_LIST_ELT (list, this_spline);
183 
184       if( SPLINE_DEGREE (s) == LINEARTYPE ){
185         print_coord(ps_file, END_POINT(s).x, END_POINT(s).y);
186       } else {
187         at_real temp;
188 	at_real dt = (at_real) (1.0/7.0);
189 	/*smooth = true;*/
190 	for( temp=dt; fabs(temp-(at_real)1.0)<dt; temp+=dt ){
191 	  print_coord(ps_file,
192 	    bezpnt(temp,START_POINT(s).x,CONTROL1(s).x,CONTROL2(s).x,END_POINT(s).x),
193 	    bezpnt(temp,START_POINT(s).y,CONTROL1(s).y,CONTROL2(s).y,END_POINT(s).y));
194 	}
195       }
196     }
197     fprintf(ps_file, "  <Smoothed %s>\n", smooth ? "Yes": "No");
198     fprintf(ps_file, " >\n");
199   }
200   fprintf(ps_file, ">\n");
201   return 0;
202 }
203