/* output-p2e.c: utility routines for pstoedit intermediate output Copyright (C) 2000-2001 Wolfgang Glunz, Martin Weber This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* Initial author: Wolfgang Glunz - wglunz@pstoedit.net use the generated file to run "pstoedit -bo -f format input output" Adapted to pstoedit 3.30 by Wolfgang Glunz. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Def: HAVE_CONFIG_H */ #include "types.h" #include "spline.h" #include "color.h" #include "output-p2e.h" #define SIGN(x) ((x) > 0 ? 1 : (x) < 0 ? -1 : 0) #define ROUND(x) ((int) ((int) (x) + .5 * SIGN (x))) /* Output macros. */ /* This should be used for outputting a string S on a line by itself. */ #define OUT_LINE(l) \ fprintf (ps_file, "%s\n", l) /* These output their arguments, preceded by the indentation. */ #define OUT1(s, e) \ fprintf (ps_file, s, e) #ifdef withrgbcolor #define OUT3(s, e1, e2, e3) fprintf (ps_file, s, e1, e2, e3) #else #define OUT5(s, e1, e2, e3, e4, e5) fprintf (ps_file, s, e1, e2, e3, e4, e5) #endif #define OUT4(s, e1, e2, e3, e4) \ fprintf (ps_file, s, e1, e2, e3, e4) /* These macros just output their arguments. */ #define OUT_STRING(st) fprintf (ps_file, "%s", st) #define OUT_REAL(r) fprintf (ps_file, \ r == ROUND (r) ? "%.0f " : "%.3f ", r) /* For a PostScript command with two real arguments, e.g., lineto. OP should be a constant string. */ #define OUT_COMMAND2(first, second, op) \ do \ { \ OUT_STRING (" "); \ OUT_REAL (first); \ OUT_REAL (second); \ OUT_STRING (op "\n"); \ } \ while (0) /* For a PostScript command with six real arguments, e.g., curveto. Again, OP should be a constant string. */ #define OUT_COMMAND6(first, second, third, fourth, fifth, sixth, op) \ do \ { \ OUT_STRING (" "); \ OUT_REAL (first); \ OUT_REAL (second); \ OUT_STRING (" "); \ OUT_REAL (third); \ OUT_REAL (fourth); \ OUT_STRING (" "); \ OUT_REAL (fifth); \ OUT_REAL (sixth); \ OUT_STRING (" " op "\n"); \ } \ while (0) /* This should be called before the others in this file. It opens the output file `OUTPUT_NAME.ps', and writes some preliminary boilerplate. */ static int output_p2e_header(FILE* ps_file, at_string name, int llx, int lly, int urx, int ury, spline_list_array_type shape) { unsigned this_list, with_curves = 1; for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) != LINEARTYPE) { with_curves = 0; this_list = SPLINE_LIST_ARRAY_LENGTH (shape); break; } } } OUT_LINE ("%!PS-Adobe-3.0"); OUT1 ("%%%%Title: flattened PostScript generated by autotrace: %s\n",name); OUT_LINE ("%%Creator: pstoedit"); OUT_LINE ("%%BoundingBox: (atend)"); OUT_LINE ("%%Pages: (atend)"); OUT_LINE ("%%EndComments"); OUT_LINE ("%%BeginProlog"); OUT_LINE ("/setPageSize { pop pop } def"); OUT_LINE ("/ntranslate { neg exch neg exch translate } def"); OUT_LINE ("/setshowparams { pop pop pop} def"); OUT_LINE ("/awidthshowhex { dup /ASCIIHexDecode filter exch length 2 div cvi string readstring pop awidthshow } def"); OUT_LINE ("/backendconstraints { pop pop } def"); 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"); OUT_LINE ("/imagestring 1 string def"); OUT_LINE ("%%EndProlog"); OUT_LINE ("%%BeginSetup"); OUT_LINE ("% textastext doflatten backendconstraints "); OUT1 ("%d 0 backendconstraints\n", with_curves); OUT_LINE ("%%EndSetup"); return 0; } /* This outputs the PostScript code which produces the shape in SHAPE. */ static void out_splines (FILE * ps_file, spline_list_array_type shape) { unsigned this_list; unsigned int pathnr = 1; spline_list_type list; color_type last_color = {0,0,0}; OUT_LINE (" 612 792 setPageSize"); OUT_LINE (" 0 setlinecap"); OUT_LINE (" 10.0 setmiterlimit"); OUT_LINE (" 0 setlinejoin"); OUT_LINE (" [ ] 0.0 setdash"); OUT_LINE (" 1.0 setlinewidth"); for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_type first; list = SPLINE_LIST_ARRAY_ELT (shape, this_list); first = SPLINE_LIST_ELT (list, 0); if (this_list == 0 || !COLOR_EQUAL(list.color, last_color)) { int c, m, y, k; OUT_LINE ((shape.centerline || list.open) ? "stroke" : "fill"); OUT1("\n\n%% %d pathnumber\n",pathnr); OUT_LINE ((shape.centerline || list.open) ? "% strokedpath" : "% filledpath"); pathnr++; #ifdef withrgbcolor // in the long term this can be removed. OUT3 ("%.3f %.3f %.3f setrgbcolor\n", (real)list.color.r/255.0, (real)list.color.g/255.0, (real)list.color.b/255.0); #else c = k = 255 - list.color.r; m = 255 - list.color.g; if (m < k) k = m; y = 255 - list.color.b; if (y < k) k = y; c -= k; m -= k; y -= k; OUT5("%.3f %.3f %.3f %.3f %s\n", (double) c/255.0, (double) m/255.0,(double) y/255.0, (double) k/255.0, "setcmykcolor"); #endif last_color = list.color; } OUT_LINE ("newpath"); OUT_COMMAND2 (START_POINT (first).x, START_POINT (first).y, "moveto"); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == LINEARTYPE) OUT_COMMAND2 (END_POINT (s).x, END_POINT (s).y, "lineto"); else OUT_COMMAND6 (CONTROL1 (s).x, CONTROL1 (s).y, CONTROL2 (s).x, CONTROL2 (s).y, END_POINT (s).x, END_POINT (s).y, "curveto"); } if (!list.open) OUT_LINE ("closepath"); } if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) OUT_LINE ((shape.centerline || list.open) ? "stroke" : "fill"); } int 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) { int result; result = output_p2e_header(ps_file, name, llx, lly, urx, ury, shape); if (result != 0) return result; out_splines(ps_file, shape); OUT_LINE ("showpage"); OUT4 ("%%%%BoundingBox: %d %d %d %d\n", llx, lly, urx, ury); OUT_LINE ("%%Page: 1 1"); OUT_LINE ("% normal end reached by pstoedit.pro"); OUT_LINE ("%%Trailer"); OUT_LINE ("%%Pages: 1"); OUT_LINE ("%%EOF"); return 0; }