1 /* output-p2e.c: utility routines for pstoedit intermediate output
2 
3    Copyright (C) 2000-2001 Wolfgang Glunz, 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 /* Initial author: Wolfgang Glunz - wglunz@pstoedit.net
21    use the generated file to run "pstoedit -bo -f format input output"
22    Adapted to pstoedit 3.30 by Wolfgang Glunz. */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif /* Def: HAVE_CONFIG_H */
27 
28 #include "types.h"
29 #include "spline.h"
30 #include "color.h"
31 #include "output-p2e.h"
32 
33 
34 #define SIGN(x) ((x) > 0 ? 1 : (x) < 0 ? -1 : 0)
35 #define ROUND(x) ((int) ((int) (x) + .5 * SIGN (x)))
36 
37 /* Output macros.  */
38 
39 /* This should be used for outputting a string S on a line by itself.  */
40 #define OUT_LINE(l)							\
41   fprintf (ps_file, "%s\n", l)
42 
43 /* These output their arguments, preceded by the indentation.  */
44 #define OUT1(s, e)							\
45   fprintf (ps_file, s, e)
46 
47 #ifdef withrgbcolor
48 #define OUT3(s, e1, e2, e3)	  fprintf (ps_file, s, e1, e2, e3)
49 #else
50 #define OUT5(s, e1, e2, e3, e4, e5)		  fprintf (ps_file, s, e1, e2, e3, e4, e5)
51 #endif
52 
53 #define OUT4(s, e1, e2, e3, e4)						\
54   fprintf (ps_file, s, e1, e2, e3, e4)
55 
56 /* These macros just output their arguments.  */
57 #define OUT_STRING(st)	fprintf (ps_file, "%s", st)
58 #define OUT_REAL(r)	fprintf (ps_file,				\
59                                  r == ROUND (r) ? "%.0f " : "%.3f ", r)
60 
61 /* For a PostScript command with two real arguments, e.g., lineto.  OP
62    should be a constant string.  */
63 #define OUT_COMMAND2(first, second, op)					\
64   do									\
65 	{								\
66       OUT_STRING (" ");							\
67       OUT_REAL (first);							\
68       OUT_REAL (second);						\
69       OUT_STRING (op "\n");						\
70     }									\
71   while (0)
72 
73 /* For a PostScript command with six real arguments, e.g., curveto.
74    Again, OP should be a constant string.  */
75 #define OUT_COMMAND6(first, second, third, fourth, fifth, sixth, op)	\
76   do									\
77     {									\
78       OUT_STRING (" ");							\
79       OUT_REAL (first);							\
80       OUT_REAL (second);						\
81       OUT_STRING (" ");							\
82       OUT_REAL (third);							\
83       OUT_REAL (fourth);						\
84       OUT_STRING (" ");							\
85       OUT_REAL (fifth);							\
86       OUT_REAL (sixth);							\
87       OUT_STRING (" " op "\n");						\
88     }									\
89    while (0)
90 
91 /* This should be called before the others in this file.  It opens the
92    output file `OUTPUT_NAME.ps', and writes some preliminary boilerplate. */
93 
output_p2e_header(FILE * ps_file,at_string name,int llx,int lly,int urx,int ury,spline_list_array_type shape)94 static int output_p2e_header(FILE* ps_file, at_string name,
95 			     int  llx, int  lly, int  urx, int  ury, spline_list_array_type shape)
96 {
97   unsigned this_list, with_curves = 1;
98 
99   for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape);
100        this_list++)
101     {
102       unsigned this_spline;
103 
104       spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
105 
106       for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list);
107            this_spline++)
108         {
109           spline_type s = SPLINE_LIST_ELT (list, this_spline);
110 
111           if (SPLINE_DEGREE (s) != LINEARTYPE)
112             {
113               with_curves = 0;
114               this_list = SPLINE_LIST_ARRAY_LENGTH (shape);
115               break;
116             }
117         }
118 
119     }
120 
121   OUT_LINE ("%!PS-Adobe-3.0");
122   OUT1     ("%%%%Title: flattened PostScript generated by autotrace: %s\n",name);
123   OUT_LINE ("%%Creator: pstoedit");
124   OUT_LINE ("%%BoundingBox: (atend)");
125   OUT_LINE ("%%Pages: (atend)");
126   OUT_LINE ("%%EndComments");
127   OUT_LINE ("%%BeginProlog");
128   OUT_LINE ("/setPageSize { pop pop } def");
129   OUT_LINE ("/ntranslate { neg exch neg exch translate } def");
130   OUT_LINE ("/setshowparams { pop pop pop} def");
131   OUT_LINE ("/awidthshowhex { dup /ASCIIHexDecode filter exch length 2 div cvi string readstring pop awidthshow } def");
132   OUT_LINE ("/backendconstraints { pop pop } def");
133   OUT_LINE ("/pstoedit.newfont { 80 string cvs  findfont  dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall  /Encoding ISOLatin1Encoding def   dup 80 string cvs /FontName exch def  currentdict end  definefont pop } def");
134   OUT_LINE ("/imagestring 1 string def");
135   OUT_LINE ("%%EndProlog");
136   OUT_LINE ("%%BeginSetup");
137   OUT_LINE ("% textastext doflatten backendconstraints  ");
138   OUT1     ("%d 0 backendconstraints\n", with_curves);
139   OUT_LINE ("%%EndSetup");
140 
141   return 0;
142 }
143 
144 /* This outputs the PostScript code which produces the shape in
145    SHAPE.  */
146 
147 static void
out_splines(FILE * ps_file,spline_list_array_type shape)148 out_splines (FILE * ps_file, spline_list_array_type shape)
149 {
150   unsigned this_list;
151   unsigned int pathnr = 1;
152   spline_list_type list;
153   color_type last_color = {0,0,0};
154 
155   OUT_LINE (" 612 792 setPageSize");
156   OUT_LINE (" 0 setlinecap");
157   OUT_LINE (" 10.0 setmiterlimit");
158   OUT_LINE (" 0 setlinejoin");
159   OUT_LINE (" [ ] 0.0 setdash");
160   OUT_LINE (" 1.0 setlinewidth");
161 
162   for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape);
163        this_list++)
164     {
165       unsigned this_spline;
166 	  spline_type first;
167 
168       list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
169       first = SPLINE_LIST_ELT (list, 0);
170 
171 
172       if (this_list == 0 || !COLOR_EQUAL(list.color, last_color))
173         {
174           int c, m, y, k;
175 
176           OUT_LINE ((shape.centerline || list.open) ? "stroke" : "fill");
177           OUT1("\n\n%% %d pathnumber\n",pathnr);
178           OUT_LINE ((shape.centerline || list.open) ? "% strokedpath" : "% filledpath");
179           pathnr++;
180 #ifdef withrgbcolor
181           // in the long term this can be removed.
182           OUT3 ("%.3f %.3f %.3f setrgbcolor\n",	(real)list.color.r/255.0,
183             (real)list.color.g/255.0,
184             (real)list.color.b/255.0);
185 #else
186           c = k = 255 - list.color.r;
187           m = 255 - list.color.g;
188           if (m < k)
189             k = m;
190           y = 255 - list.color.b;
191           if (y < k)
192             k = y;
193           c -= k;
194           m -= k;
195           y -= k;
196           OUT5("%.3f %.3f %.3f %.3f %s\n", (double) c/255.0, (double) m/255.0,(double) y/255.0, (double) k/255.0, "setcmykcolor");
197 #endif
198           last_color = list.color;
199         }
200 
201       OUT_LINE ("newpath");
202       OUT_COMMAND2 (START_POINT (first).x, START_POINT (first).y, "moveto");
203 
204       for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list);
205         this_spline++)
206         {
207           spline_type s = SPLINE_LIST_ELT (list, this_spline);
208 
209           if (SPLINE_DEGREE (s) == LINEARTYPE)
210             OUT_COMMAND2 (END_POINT (s).x, END_POINT (s).y, "lineto");
211           else
212             OUT_COMMAND6 (CONTROL1 (s).x, CONTROL1 (s).y,
213               CONTROL2 (s).x, CONTROL2 (s).y,
214               END_POINT (s).x, END_POINT (s).y,
215               "curveto");
216         }
217       if (!list.open) OUT_LINE ("closepath");
218     }
219   if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0)
220     OUT_LINE ((shape.centerline || list.open) ? "stroke" : "fill");
221 }
222 
223 
output_p2e_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)224 int output_p2e_writer(FILE* ps_file, at_string name,
225 		      int llx, int lly, int urx, int ury,
226 		      at_output_opts_type * opts,
227 		      spline_list_array_type shape,
228 		      at_msg_func msg_func,
229 		      at_address msg_data)
230 {
231   int result;
232 
233   result = output_p2e_header(ps_file, name, llx, lly, urx, ury, shape);
234   if (result != 0)  return result;
235 
236   out_splines(ps_file, shape);
237 
238   OUT_LINE ("showpage");
239   OUT4 ("%%%%BoundingBox: %d %d %d %d\n", llx, lly, urx, ury);
240   OUT_LINE ("%%Page: 1 1");
241   OUT_LINE ("% normal end reached by pstoedit.pro");
242   OUT_LINE ("%%Trailer");
243   OUT_LINE ("%%Pages: 1");
244   OUT_LINE ("%%EOF");
245 
246   return 0;
247 }
248