xref: /plan9/sys/src/cmd/aux/antiword/postscript.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier  * postscript.c
3*25b329d5SDavid du Colombier  * Copyright (C) 1999-2005 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier  *
5f5736e95SDavid du Colombier  * Description:
6f5736e95SDavid du Colombier  * Functions to deal with the PostScript format
7f5736e95SDavid du Colombier  *
8f5736e95SDavid du Colombier  *================================================================
9f5736e95SDavid du Colombier  * The function vImagePrologue is based on:
10f5736e95SDavid du Colombier  * jpeg2ps - convert JPEG compressed images to PostScript Level 2
11f5736e95SDavid du Colombier  * Copyright (C) 1994-99 Thomas Merz (tm@muc.de)
12f5736e95SDavid du Colombier  *================================================================
13f5736e95SDavid du Colombier  * The credit should go to him, but all the bugs are mine.
14f5736e95SDavid du Colombier  */
15f5736e95SDavid du Colombier 
16f5736e95SDavid du Colombier #include <stdlib.h>
17f5736e95SDavid du Colombier #include <errno.h>
18f5736e95SDavid du Colombier #include <time.h>
19f5736e95SDavid du Colombier #include <string.h>
20f5736e95SDavid du Colombier #include "version.h"
21f5736e95SDavid du Colombier #include "antiword.h"
22f5736e95SDavid du Colombier 
23f5736e95SDavid du Colombier /* The character set */
24f5736e95SDavid du Colombier static encoding_type	eEncoding = encoding_neutral;
25f5736e95SDavid du Colombier /* The image level */
26f5736e95SDavid du Colombier static image_level_enum	eImageLevel = level_default;
27f5736e95SDavid du Colombier /* The output must use landscape orientation */
28f5736e95SDavid du Colombier static BOOL		bUseLandscape = FALSE;
29f5736e95SDavid du Colombier /* The height and width of a PostScript page (in DrawUnits) */
30f5736e95SDavid du Colombier static long		lPageHeight = LONG_MAX;
31f5736e95SDavid du Colombier static long		lPageWidth = LONG_MAX;
32*25b329d5SDavid du Colombier /* The height of the footer on the current page (in DrawUnits) */
33*25b329d5SDavid du Colombier static long		lFooterHeight = 0;
34*25b329d5SDavid du Colombier /* Inside a footer (to prevent an infinite loop when the footer is too big) */
35*25b329d5SDavid du Colombier static BOOL		bInFtrSpace = FALSE;
36f5736e95SDavid du Colombier /* Current time for a PS header */
37f5736e95SDavid du Colombier static const char	*szCreationDate = NULL;
38f5736e95SDavid du Colombier /* Current creator for a PS header */
39f5736e95SDavid du Colombier static const char	*szCreator = NULL;
40f5736e95SDavid du Colombier /* Current font information */
41*25b329d5SDavid du Colombier static drawfile_fontref	tFontRefCurr = (drawfile_fontref)-1;
42f5736e95SDavid du Colombier static USHORT		usFontSizeCurr = 0;
43f5736e95SDavid du Colombier static int		iFontColorCurr = -1;
44f5736e95SDavid du Colombier /* Current vertical position information */
45f5736e95SDavid du Colombier static long		lYtopCurr = -1;
46f5736e95SDavid du Colombier /* PostScript page counter */
47f5736e95SDavid du Colombier static int		iPageCount = 0;
48f5736e95SDavid du Colombier /* Image counter */
49f5736e95SDavid du Colombier static int		iImageCount = 0;
50*25b329d5SDavid du Colombier /* Section index */
51*25b329d5SDavid du Colombier static int		iSectionIndex = 0;
52*25b329d5SDavid du Colombier /* Are we on the first page of the section? */
53*25b329d5SDavid du Colombier static BOOL		bFirstInSection = TRUE;
54*25b329d5SDavid du Colombier 
55*25b329d5SDavid du Colombier static void		vMoveTo(diagram_type *, long);
56f5736e95SDavid du Colombier 
57f5736e95SDavid du Colombier static const char *iso_8859_1_data[] = {
58f5736e95SDavid du Colombier "/newcodes	% ISO-8859-1 character encodings",
59f5736e95SDavid du Colombier "[",
60f5736e95SDavid du Colombier "140/ellipsis 141/trademark 142/perthousand 143/bullet",
61f5736e95SDavid du Colombier "144/quoteleft 145/quoteright 146/guilsinglleft 147/guilsinglright",
62f5736e95SDavid du Colombier "148/quotedblleft 149/quotedblright 150/quotedblbase 151/endash 152/emdash",
63f5736e95SDavid du Colombier "153/minus 154/OE 155/oe 156/dagger 157/daggerdbl 158/fi 159/fl",
64f5736e95SDavid du Colombier "160/space 161/exclamdown 162/cent 163/sterling 164/currency",
65f5736e95SDavid du Colombier "165/yen 166/brokenbar 167/section 168/dieresis 169/copyright",
66f5736e95SDavid du Colombier "170/ordfeminine 171/guillemotleft 172/logicalnot 173/hyphen 174/registered",
67f5736e95SDavid du Colombier "175/macron 176/degree 177/plusminus 178/twosuperior 179/threesuperior",
68f5736e95SDavid du Colombier "180/acute 181/mu 182/paragraph 183/periodcentered 184/cedilla",
69f5736e95SDavid du Colombier "185/onesuperior 186/ordmasculine 187/guillemotright 188/onequarter",
70f5736e95SDavid du Colombier "189/onehalf 190/threequarters 191/questiondown 192/Agrave 193/Aacute",
71f5736e95SDavid du Colombier "194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198/AE 199/Ccedilla",
72f5736e95SDavid du Colombier "200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204/Igrave 205/Iacute",
73f5736e95SDavid du Colombier "206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve 211/Oacute",
74f5736e95SDavid du Colombier "212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash",
75f5736e95SDavid du Colombier "217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn",
76f5736e95SDavid du Colombier "223/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde",
77f5736e95SDavid du Colombier "228/adieresis 229/aring 230/ae 231/ccedilla 232/egrave 233/eacute",
78f5736e95SDavid du Colombier "234/ecircumflex 235/edieresis 236/igrave 237/iacute 238/icircumflex",
79f5736e95SDavid du Colombier "239/idieresis 240/eth 241/ntilde 242/ograve 243/oacute 244/ocircumflex",
80f5736e95SDavid du Colombier "245/otilde 246/odieresis 247/divide 248/oslash 249/ugrave 250/uacute",
81f5736e95SDavid du Colombier "251/ucircumflex 252/udieresis 253/yacute 254/thorn 255/ydieresis",
82f5736e95SDavid du Colombier "] bind def",
83f5736e95SDavid du Colombier "",
84f5736e95SDavid du Colombier "/reencdict 12 dict def",
85f5736e95SDavid du Colombier "",
86f5736e95SDavid du Colombier };
87f5736e95SDavid du Colombier 
88f5736e95SDavid du Colombier static const char *iso_8859_2_data[] = {
89f5736e95SDavid du Colombier "/newcodes	% ISO-8859-2 character encodings",
90f5736e95SDavid du Colombier "[",
91f5736e95SDavid du Colombier "160/space 161/Aogonek 162/breve 163/Lslash 164/currency 165/Lcaron",
92f5736e95SDavid du Colombier "166/Sacute 167/section 168/dieresis 169/Scaron 170/Scommaaccent",
93f5736e95SDavid du Colombier "171/Tcaron 172/Zacute 173/hyphen 174/Zcaron 175/Zdotaccent 176/degree",
94f5736e95SDavid du Colombier "177/aogonek 178/ogonek 179/lslash 180/acute 181/lcaron 182/sacute",
95f5736e95SDavid du Colombier "183/caron 184/cedilla 185/scaron 186/scommaaccent 187/tcaron",
96f5736e95SDavid du Colombier "188/zacute 189/hungarumlaut 190/zcaron 191/zdotaccent 192/Racute",
97f5736e95SDavid du Colombier "193/Aacute 194/Acircumflex 195/Abreve 196/Adieresis 197/Lacute",
98f5736e95SDavid du Colombier "198/Cacute 199/Ccedilla 200/Ccaron 201/Eacute 202/Eogonek",
99f5736e95SDavid du Colombier "203/Edieresis 204/Ecaron 205/Iacute 206/Icircumflex 207/Dcaron",
100f5736e95SDavid du Colombier "208/Dcroat 209/Nacute 210/Ncaron 211/Oacute 212/Ocircumflex",
101f5736e95SDavid du Colombier "213/Ohungarumlaut 214/Odieresis 215/multiply 216/Rcaron 217/Uring",
102f5736e95SDavid du Colombier "218/Uacute 219/Uhungarumlaut 220/Udieresis 221/Yacute 222/Tcommaaccent",
103f5736e95SDavid du Colombier "223/germandbls 224/racute 225/aacute 226/acircumflex 227/abreve",
104f5736e95SDavid du Colombier "228/adieresis 229/lacute 230/cacute 231/ccedilla 232/ccaron 233/eacute",
105f5736e95SDavid du Colombier "234/eogonek 235/edieresis 236/ecaron 237/iacute 238/icircumflex",
106f5736e95SDavid du Colombier "239/dcaron 240/dcroat 241/nacute 242/ncaron 243/oacute 244/ocircumflex",
107f5736e95SDavid du Colombier "245/ohungarumlaut 246/odieresis 247/divide 248/rcaron 249/uring",
108f5736e95SDavid du Colombier "250/uacute 251/uhungarumlaut 252/udieresis 253/yacute 254/tcommaaccent",
109f5736e95SDavid du Colombier "255/dotaccent",
110f5736e95SDavid du Colombier "] bind def",
111f5736e95SDavid du Colombier "",
112f5736e95SDavid du Colombier "/reencdict 12 dict def",
113f5736e95SDavid du Colombier "",
114f5736e95SDavid du Colombier };
115f5736e95SDavid du Colombier 
116*25b329d5SDavid du Colombier static const char *iso_8859_5_data[] = {
117*25b329d5SDavid du Colombier "/newcodes	% ISO-8859-5 character encodings",
118*25b329d5SDavid du Colombier "[",
119*25b329d5SDavid du Colombier "160/space     161/afii10023 162/afii10051 163/afii10052 164/afii10053",
120*25b329d5SDavid du Colombier "165/afii10054 166/afii10055 167/afii10056 168/afii10057 169/afii10058",
121*25b329d5SDavid du Colombier "170/afii10059 171/afii10060 172/afii10061 173/hyphen    174/afii10062",
122*25b329d5SDavid du Colombier "175/afii10145 176/afii10017 177/afii10018 178/afii10019 179/afii10020",
123*25b329d5SDavid du Colombier "180/afii10021 181/afii10022 182/afii10024 183/afii10025 184/afii10026",
124*25b329d5SDavid du Colombier "185/afii10027 186/afii10028 187/afii10029 188/afii10030 189/afii10031",
125*25b329d5SDavid du Colombier "190/afii10032 191/afii10033 192/afii10034 193/afii10035 194/afii10036",
126*25b329d5SDavid du Colombier "195/afii10037 196/afii10038 197/afii10039 198/afii10040 199/afii10041",
127*25b329d5SDavid du Colombier "200/afii10042 201/afii10043 202/afii10044 203/afii10045 204/afii10046",
128*25b329d5SDavid du Colombier "205/afii10047 206/afii10048 207/afii10049 208/afii10065 209/afii10066",
129*25b329d5SDavid du Colombier "210/afii10067 211/afii10068 212/afii10069 213/afii10070 214/afii10072",
130*25b329d5SDavid du Colombier "215/afii10073 216/afii10074 217/afii10075 218/afii10076 219/afii10077",
131*25b329d5SDavid du Colombier "220/afii10078 221/afii10079 222/afii10080 223/afii10081 224/afii10082",
132*25b329d5SDavid du Colombier "225/afii10083 226/afii10084 227/afii10085 228/afii10086 229/afii10087",
133*25b329d5SDavid du Colombier "230/afii10088 231/afii10089 232/afii10090 233/afii10091 234/afii10092",
134*25b329d5SDavid du Colombier "235/afii10093 236/afii10094 237/afii10095 238/afii10096 239/afii10097",
135*25b329d5SDavid du Colombier "240/afii61352 241/afii10071 242/afii10099 243/afii10100 244/afii10101",
136*25b329d5SDavid du Colombier "245/afii10102 246/afii10103 247/afii10104 248/afii10105 249/afii10106",
137*25b329d5SDavid du Colombier "250/afii10107 251/afii10108 252/afii10109 253/section   254/afii10110",
138*25b329d5SDavid du Colombier "255/afii10193",
139*25b329d5SDavid du Colombier "] bind def",
140*25b329d5SDavid du Colombier "",
141*25b329d5SDavid du Colombier "/reencdict 12 dict def",
142*25b329d5SDavid du Colombier "",
143*25b329d5SDavid du Colombier };
144*25b329d5SDavid du Colombier 
145f5736e95SDavid du Colombier static const char *iso_8859_x_func[] = {
146f5736e95SDavid du Colombier "% change fonts using ISO-8859-x characters",
147f5736e95SDavid du Colombier "/ChgFnt		% size psname natname => font",
148f5736e95SDavid du Colombier "{",
149f5736e95SDavid du Colombier "	dup FontDirectory exch known		% is re-encoded name known?",
150f5736e95SDavid du Colombier "	{ exch pop }				% yes, get rid of long name",
151f5736e95SDavid du Colombier "	{ dup 3 1 roll ReEncode } ifelse	% no, re-encode it",
152f5736e95SDavid du Colombier "	findfont exch scalefont setfont",
153f5736e95SDavid du Colombier "} bind def",
154f5736e95SDavid du Colombier "",
155f5736e95SDavid du Colombier "/ReEncode",
156f5736e95SDavid du Colombier "{",
157f5736e95SDavid du Colombier "reencdict begin",
158f5736e95SDavid du Colombier "	/newname exch def",
159f5736e95SDavid du Colombier "	/basename exch def",
160f5736e95SDavid du Colombier "	/basedict basename findfont def",
161f5736e95SDavid du Colombier "	/newfont basedict maxlength dict def",
162f5736e95SDavid du Colombier "	basedict",
163f5736e95SDavid du Colombier "	{ exch dup /FID ne",
164f5736e95SDavid du Colombier "		{ dup /Encoding eq",
165f5736e95SDavid du Colombier "			{ exch dup length array copy newfont 3 1 roll put }",
166f5736e95SDavid du Colombier "			{ exch newfont 3 1 roll put } ifelse",
167f5736e95SDavid du Colombier "		}",
168f5736e95SDavid du Colombier "		{ pop pop } ifelse",
169f5736e95SDavid du Colombier "	} forall",
170f5736e95SDavid du Colombier "	newfont /FontName newname put",
171f5736e95SDavid du Colombier "	newcodes aload pop newcodes length 2 idiv",
172f5736e95SDavid du Colombier "	{ newfont /Encoding get 3 1 roll put } repeat",
173f5736e95SDavid du Colombier "	newname newfont definefont pop",
174f5736e95SDavid du Colombier "end",
175f5736e95SDavid du Colombier "} bind def",
176f5736e95SDavid du Colombier "",
177f5736e95SDavid du Colombier };
178f5736e95SDavid du Colombier 
179f5736e95SDavid du Colombier static const char *misc_func[] = {
180f5736e95SDavid du Colombier "% draw a line and show the string",
181f5736e95SDavid du Colombier "/LineShow	% string linewidth movement",
182f5736e95SDavid du Colombier "{",
183f5736e95SDavid du Colombier "	gsave",
184f5736e95SDavid du Colombier "		0 exch rmoveto",
185f5736e95SDavid du Colombier "		setlinewidth",
186f5736e95SDavid du Colombier "		dup",
187f5736e95SDavid du Colombier "		stringwidth pop",
188f5736e95SDavid du Colombier "		0 rlineto stroke",
189f5736e95SDavid du Colombier "	grestore",
190f5736e95SDavid du Colombier "	show",
191f5736e95SDavid du Colombier "} bind def",
192f5736e95SDavid du Colombier "",
193f5736e95SDavid du Colombier "% begin an EPS file (level 2 and up)",
194f5736e95SDavid du Colombier "/BeginEPSF",
195f5736e95SDavid du Colombier "{",
196f5736e95SDavid du Colombier "	/b4_Inc_state save def",
197f5736e95SDavid du Colombier "	/dict_count countdictstack def",
198f5736e95SDavid du Colombier "	/op_count count 1 sub def",
199f5736e95SDavid du Colombier "	userdict begin",
200f5736e95SDavid du Colombier "		/showpage { } def",
201f5736e95SDavid du Colombier "		0 setgray 0 setlinecap",
202f5736e95SDavid du Colombier "		1 setlinewidth 0 setlinejoin",
203f5736e95SDavid du Colombier "		10 setmiterlimit [ ] 0 setdash newpath",
204f5736e95SDavid du Colombier "		false setstrokeadjust false setoverprint",
205f5736e95SDavid du Colombier "} bind def",
206f5736e95SDavid du Colombier "",
207f5736e95SDavid du Colombier "% end an EPS file",
208f5736e95SDavid du Colombier "/EndEPSF {",
209f5736e95SDavid du Colombier "	count op_count sub { pop } repeat",
210f5736e95SDavid du Colombier "	countdictstack dict_count sub { end } repeat",
211f5736e95SDavid du Colombier "	b4_Inc_state restore",
212f5736e95SDavid du Colombier "} bind def",
213f5736e95SDavid du Colombier "",
214f5736e95SDavid du Colombier };
215f5736e95SDavid du Colombier 
216f5736e95SDavid du Colombier 
217f5736e95SDavid du Colombier /*
218f5736e95SDavid du Colombier  * vAddPageSetup - add the page setup
219f5736e95SDavid du Colombier  */
220f5736e95SDavid du Colombier static void
vAddPageSetup(FILE * pOutFile)221f5736e95SDavid du Colombier vAddPageSetup(FILE *pOutFile)
222f5736e95SDavid du Colombier {
223f5736e95SDavid du Colombier 	if (bUseLandscape) {
224f5736e95SDavid du Colombier 		fprintf(pOutFile, "%%%%BeginPageSetup\n");
225f5736e95SDavid du Colombier 		fprintf(pOutFile, "90 rotate\n");
226f5736e95SDavid du Colombier 		fprintf(pOutFile, "0.00 %.2f translate\n",
227f5736e95SDavid du Colombier 					-dDrawUnits2Points(lPageHeight));
228f5736e95SDavid du Colombier 		fprintf(pOutFile, "%%%%EndPageSetup\n");
229f5736e95SDavid du Colombier 	}
230f5736e95SDavid du Colombier } /* end of vAddPageSetup */
231f5736e95SDavid du Colombier 
232f5736e95SDavid du Colombier /*
233*25b329d5SDavid du Colombier  * vAddHdrFtr - add a header or footer
234*25b329d5SDavid du Colombier  */
235*25b329d5SDavid du Colombier static void
vAddHdrFtr(diagram_type * pDiag,const hdrftr_block_type * pHdrFtrInfo)236*25b329d5SDavid du Colombier vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo)
237*25b329d5SDavid du Colombier {
238*25b329d5SDavid du Colombier 	output_type	*pStart, *pPrev, *pNext;
239*25b329d5SDavid du Colombier 
240*25b329d5SDavid du Colombier 	fail(pDiag == NULL);
241*25b329d5SDavid du Colombier 	fail(pHdrFtrInfo == NULL);
242*25b329d5SDavid du Colombier 
243*25b329d5SDavid du Colombier 	vStartOfParagraphPS(pDiag, 0);
244*25b329d5SDavid du Colombier 	pStart = pHdrFtrInfo->pText;
245*25b329d5SDavid du Colombier 	while (pStart != NULL) {
246*25b329d5SDavid du Colombier 		pNext = pStart;
247*25b329d5SDavid du Colombier 		while (pNext != NULL &&
248*25b329d5SDavid du Colombier 		       (pNext->tNextFree != 1 ||
249*25b329d5SDavid du Colombier 		        (pNext->szStorage[0] != PAR_END &&
250*25b329d5SDavid du Colombier 		         pNext->szStorage[0] != HARD_RETURN))) {
251*25b329d5SDavid du Colombier 			pNext = pNext->pNext;
252*25b329d5SDavid du Colombier 		}
253*25b329d5SDavid du Colombier 		if (pNext == NULL) {
254*25b329d5SDavid du Colombier 			if (bOutputContainsText(pStart)) {
255*25b329d5SDavid du Colombier 				vAlign2Window(pDiag, pStart,
256*25b329d5SDavid du Colombier 					lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
257*25b329d5SDavid du Colombier 					ALIGNMENT_LEFT);
258*25b329d5SDavid du Colombier 			} else {
259*25b329d5SDavid du Colombier 				vMove2NextLinePS(pDiag, pStart->usFontSize);
260*25b329d5SDavid du Colombier 			}
261*25b329d5SDavid du Colombier 			break;
262*25b329d5SDavid du Colombier 		}
263*25b329d5SDavid du Colombier 		fail(pNext->tNextFree != 1);
264*25b329d5SDavid du Colombier 		fail(pNext->szStorage[0] != PAR_END &&
265*25b329d5SDavid du Colombier 			pNext->szStorage[0] != HARD_RETURN);
266*25b329d5SDavid du Colombier 
267*25b329d5SDavid du Colombier 		if (pStart != pNext) {
268*25b329d5SDavid du Colombier 			/* There is something to print */
269*25b329d5SDavid du Colombier 			pPrev = pNext->pPrev;
270*25b329d5SDavid du Colombier 			fail(pPrev->pNext != pNext);
271*25b329d5SDavid du Colombier 			/* Cut the chain */
272*25b329d5SDavid du Colombier 			pPrev->pNext = NULL;
273*25b329d5SDavid du Colombier 			if (bOutputContainsText(pStart)) {
274*25b329d5SDavid du Colombier 				/* Print it */
275*25b329d5SDavid du Colombier 				vAlign2Window(pDiag, pStart,
276*25b329d5SDavid du Colombier 					lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
277*25b329d5SDavid du Colombier 					ALIGNMENT_LEFT);
278*25b329d5SDavid du Colombier 			} else {
279*25b329d5SDavid du Colombier 				/* Just an empty line */
280*25b329d5SDavid du Colombier 				vMove2NextLinePS(pDiag, pStart->usFontSize);
281*25b329d5SDavid du Colombier 			}
282*25b329d5SDavid du Colombier 			/* Repair the chain */
283*25b329d5SDavid du Colombier 			pPrev->pNext = pNext;
284*25b329d5SDavid du Colombier 		}
285*25b329d5SDavid du Colombier 		if (pNext->szStorage[0] == PAR_END) {
286*25b329d5SDavid du Colombier 			vEndOfParagraphPS(pDiag, pNext->usFontSize,
287*25b329d5SDavid du Colombier 					(long)pNext->usFontSize * 200);
288*25b329d5SDavid du Colombier 		}
289*25b329d5SDavid du Colombier 		pStart = pNext->pNext;
290*25b329d5SDavid du Colombier 	}
291*25b329d5SDavid du Colombier } /* end of vAddHdrFtr */
292*25b329d5SDavid du Colombier 
293*25b329d5SDavid du Colombier /*
294*25b329d5SDavid du Colombier  * vAddHeader - add a page header
295*25b329d5SDavid du Colombier  */
296*25b329d5SDavid du Colombier static void
vAddHeader(diagram_type * pDiag)297*25b329d5SDavid du Colombier vAddHeader(diagram_type *pDiag)
298*25b329d5SDavid du Colombier {
299*25b329d5SDavid du Colombier 	const hdrftr_block_type	*pHdrInfo;
300*25b329d5SDavid du Colombier 	const hdrftr_block_type	*pFtrInfo;
301*25b329d5SDavid du Colombier 
302*25b329d5SDavid du Colombier 	fail(pDiag == NULL);
303*25b329d5SDavid du Colombier 
304*25b329d5SDavid du Colombier 	NO_DBG_MSG("vAddHeader");
305*25b329d5SDavid du Colombier 
306*25b329d5SDavid du Colombier 	pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE,
307*25b329d5SDavid du Colombier 					odd(iPageCount), bFirstInSection);
308*25b329d5SDavid du Colombier 	pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
309*25b329d5SDavid du Colombier 					odd(iPageCount), bFirstInSection);
310*25b329d5SDavid du Colombier 	/* Set the height of the footer of this page */
311*25b329d5SDavid du Colombier 	lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight;
312*25b329d5SDavid du Colombier 	fail(lFooterHeight < 0);
313*25b329d5SDavid du Colombier 
314*25b329d5SDavid du Colombier 	if (pHdrInfo == NULL ||
315*25b329d5SDavid du Colombier 	    pHdrInfo->pText == NULL ||
316*25b329d5SDavid du Colombier 	    pHdrInfo->lHeight <= 0) {
317*25b329d5SDavid du Colombier 		fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0);
318*25b329d5SDavid du Colombier 		fail(pHdrInfo != NULL &&
319*25b329d5SDavid du Colombier 			pHdrInfo->pText != NULL &&
320*25b329d5SDavid du Colombier 			pHdrInfo->lHeight == 0);
321*25b329d5SDavid du Colombier 		return;
322*25b329d5SDavid du Colombier 	}
323*25b329d5SDavid du Colombier 
324*25b329d5SDavid du Colombier 	vAddHdrFtr(pDiag, pHdrInfo);
325*25b329d5SDavid du Colombier 
326*25b329d5SDavid du Colombier 	DBG_DEC_C(pHdrInfo->lHeight !=
327*25b329d5SDavid du Colombier 		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
328*25b329d5SDavid du Colombier 		pHdrInfo->lHeight);
329*25b329d5SDavid du Colombier 	DBG_DEC_C(pHdrInfo->lHeight !=
330*25b329d5SDavid du Colombier 		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
331*25b329d5SDavid du Colombier 		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
332*25b329d5SDavid du Colombier 
333*25b329d5SDavid du Colombier #if 0 /* defined(DEBUG) */
334*25b329d5SDavid du Colombier 	fprintf(pDiag->pOutFile,
335*25b329d5SDavid du Colombier 	"(HEADER: FileOffset 0x%04lx-0x%04lx; Height %ld-%ld) show\n",
336*25b329d5SDavid du Colombier 		ulCharPos2FileOffset(pHdrInfo->ulCharPosStart),
337*25b329d5SDavid du Colombier 		ulCharPos2FileOffset(pHdrInfo->ulCharPosNext),
338*25b329d5SDavid du Colombier 		pHdrInfo->lHeight,
339*25b329d5SDavid du Colombier 		lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
340*25b329d5SDavid du Colombier #endif
341*25b329d5SDavid du Colombier } /* end of vAddHeader */
342*25b329d5SDavid du Colombier 
343*25b329d5SDavid du Colombier /*
344*25b329d5SDavid du Colombier  * vAddFooter - add a page footer
345*25b329d5SDavid du Colombier  */
346*25b329d5SDavid du Colombier static void
vAddFooter(diagram_type * pDiag)347*25b329d5SDavid du Colombier vAddFooter(diagram_type *pDiag)
348*25b329d5SDavid du Colombier {
349*25b329d5SDavid du Colombier 	const hdrftr_block_type	*pFtrInfo;
350*25b329d5SDavid du Colombier 
351*25b329d5SDavid du Colombier 	fail(pDiag == NULL);
352*25b329d5SDavid du Colombier 
353*25b329d5SDavid du Colombier 	NO_DBG_MSG("vAddFooter");
354*25b329d5SDavid du Colombier 	pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
355*25b329d5SDavid du Colombier 					odd(iPageCount), bFirstInSection);
356*25b329d5SDavid du Colombier 	bFirstInSection = FALSE;
357*25b329d5SDavid du Colombier 	if (pFtrInfo == NULL ||
358*25b329d5SDavid du Colombier 	    pFtrInfo->pText == NULL ||
359*25b329d5SDavid du Colombier 	    pFtrInfo->lHeight <= 0) {
360*25b329d5SDavid du Colombier 		fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0);
361*25b329d5SDavid du Colombier 		fail(pFtrInfo != NULL &&
362*25b329d5SDavid du Colombier 			pFtrInfo->pText != NULL &&
363*25b329d5SDavid du Colombier 			pFtrInfo->lHeight == 0);
364*25b329d5SDavid du Colombier 		return;
365*25b329d5SDavid du Colombier 	}
366*25b329d5SDavid du Colombier 
367*25b329d5SDavid du Colombier 	bInFtrSpace = TRUE;
368*25b329d5SDavid du Colombier 
369*25b329d5SDavid du Colombier 	DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight);
370*25b329d5SDavid du Colombier 	DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight);
371*25b329d5SDavid du Colombier 	DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
372*25b329d5SDavid du Colombier 			pDiag->lYtop);
373*25b329d5SDavid du Colombier 	DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
374*25b329d5SDavid du Colombier 			lFooterHeight + PS_BOTTOM_MARGIN);
375*25b329d5SDavid du Colombier 
376*25b329d5SDavid du Colombier 	if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) {
377*25b329d5SDavid du Colombier 		/* Move down to the start of the footer */
378*25b329d5SDavid du Colombier 		pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
379*25b329d5SDavid du Colombier 		vMoveTo(pDiag, 0);
380*25b329d5SDavid du Colombier 	} else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) {
381*25b329d5SDavid du Colombier 		DBG_FIXME();
382*25b329d5SDavid du Colombier 		/*
383*25b329d5SDavid du Colombier 		 * Move up to the start of the footer, to prevent moving
384*25b329d5SDavid du Colombier 		 * of the bottom edge of the paper
385*25b329d5SDavid du Colombier 		 */
386*25b329d5SDavid du Colombier 		pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
387*25b329d5SDavid du Colombier 		vMoveTo(pDiag, 0);
388*25b329d5SDavid du Colombier 	}
389*25b329d5SDavid du Colombier 
390*25b329d5SDavid du Colombier 	DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
391*25b329d5SDavid du Colombier 	dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop));
392*25b329d5SDavid du Colombier 
393*25b329d5SDavid du Colombier #if 0 /* defined(DEBUG) */
394*25b329d5SDavid du Colombier 	fprintf(pDiag->pOutFile,
395*25b329d5SDavid du Colombier 	"(FOOTER: FileOffset 0x%04lx-0x%04lx; Bottom %ld-%ld) show\n",
396*25b329d5SDavid du Colombier 		ulCharPos2FileOffset(pFtrInfo->ulCharPosStart),
397*25b329d5SDavid du Colombier 		ulCharPos2FileOffset(pFtrInfo->ulCharPosNext),
398*25b329d5SDavid du Colombier 		pDiag->lYtop,
399*25b329d5SDavid du Colombier 		pFtrInfo->lHeight + PS_BOTTOM_MARGIN);
400*25b329d5SDavid du Colombier #endif
401*25b329d5SDavid du Colombier 	vAddHdrFtr(pDiag, pFtrInfo);
402*25b329d5SDavid du Colombier 	bInFtrSpace = FALSE;
403*25b329d5SDavid du Colombier } /* end of vAddFooter */
404*25b329d5SDavid du Colombier 
405*25b329d5SDavid du Colombier /*
406f5736e95SDavid du Colombier  * vMove2NextPage - move to the start of the next page
407f5736e95SDavid du Colombier  */
408f5736e95SDavid du Colombier static void
vMove2NextPage(diagram_type * pDiag,BOOL bNewSection)409*25b329d5SDavid du Colombier vMove2NextPage(diagram_type *pDiag, BOOL bNewSection)
410f5736e95SDavid du Colombier {
411f5736e95SDavid du Colombier 	fail(pDiag == NULL);
412f5736e95SDavid du Colombier 
413*25b329d5SDavid du Colombier 	vAddFooter(pDiag);
414f5736e95SDavid du Colombier 	fprintf(pDiag->pOutFile, "showpage\n");
415f5736e95SDavid du Colombier 	iPageCount++;
416f5736e95SDavid du Colombier 	fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount);
417*25b329d5SDavid du Colombier 	if (bNewSection) {
418*25b329d5SDavid du Colombier 		iSectionIndex++;
419*25b329d5SDavid du Colombier 		bFirstInSection = TRUE;
420*25b329d5SDavid du Colombier 	}
421f5736e95SDavid du Colombier 	vAddPageSetup(pDiag->pOutFile);
422f5736e95SDavid du Colombier 	pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
423f5736e95SDavid du Colombier 	lYtopCurr = -1;
424*25b329d5SDavid du Colombier 	vAddHeader(pDiag);
425f5736e95SDavid du Colombier } /* end of vMove2NextPage */
426f5736e95SDavid du Colombier 
427f5736e95SDavid du Colombier /*
428*25b329d5SDavid du Colombier  * vMoveTo - move to the specified X,Y coordinates
429f5736e95SDavid du Colombier  *
430f5736e95SDavid du Colombier  * Move the current position of the specified diagram to its X,Y coordinates,
431f5736e95SDavid du Colombier  * start on a new page if needed
432f5736e95SDavid du Colombier  */
433f5736e95SDavid du Colombier static void
vMoveTo(diagram_type * pDiag,long lLastVerticalMovement)434*25b329d5SDavid du Colombier vMoveTo(diagram_type *pDiag, long lLastVerticalMovement)
435f5736e95SDavid du Colombier {
436f5736e95SDavid du Colombier 	fail(pDiag == NULL);
437f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
438f5736e95SDavid du Colombier 
439*25b329d5SDavid du Colombier 	if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) {
440*25b329d5SDavid du Colombier 		vMove2NextPage(pDiag, FALSE);
441f5736e95SDavid du Colombier 		/* Repeat the last vertical movement on the new page */
442f5736e95SDavid du Colombier 		pDiag->lYtop -= lLastVerticalMovement;
443f5736e95SDavid du Colombier 	}
444*25b329d5SDavid du Colombier 
445*25b329d5SDavid du Colombier 	fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace);
446*25b329d5SDavid du Colombier 	DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop);
447*25b329d5SDavid du Colombier 	fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3);
448f5736e95SDavid du Colombier 
449f5736e95SDavid du Colombier 	if (pDiag->lYtop != lYtopCurr) {
450f5736e95SDavid du Colombier 		fprintf(pDiag->pOutFile, "%.2f %.2f moveto\n",
451f5736e95SDavid du Colombier 			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
452f5736e95SDavid du Colombier 			dDrawUnits2Points(pDiag->lYtop));
453f5736e95SDavid du Colombier 		lYtopCurr = pDiag->lYtop;
454f5736e95SDavid du Colombier 	}
455*25b329d5SDavid du Colombier } /* end of vMoveTo */
456f5736e95SDavid du Colombier 
457f5736e95SDavid du Colombier /*
458f5736e95SDavid du Colombier  * vProloguePS - set options and perform the PostScript initialization
459f5736e95SDavid du Colombier  */
460f5736e95SDavid du Colombier void
vProloguePS(diagram_type * pDiag,const char * szTask,const char * szFilename,const options_type * pOptions)461f5736e95SDavid du Colombier vProloguePS(diagram_type *pDiag,
462f5736e95SDavid du Colombier 	const char *szTask, const char *szFilename,
463f5736e95SDavid du Colombier 	const options_type *pOptions)
464f5736e95SDavid du Colombier {
465f5736e95SDavid du Colombier 	FILE	*pOutFile;
466f5736e95SDavid du Colombier 	const char	*szTmp;
467f5736e95SDavid du Colombier 	time_t	tTime;
468f5736e95SDavid du Colombier 
469f5736e95SDavid du Colombier 	fail(pDiag == NULL);
470f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
471f5736e95SDavid du Colombier 	fail(szTask == NULL || szTask[0] == '\0');
472f5736e95SDavid du Colombier 	fail(pOptions == NULL);
473f5736e95SDavid du Colombier 
474f5736e95SDavid du Colombier 	pOutFile = pDiag->pOutFile;
475f5736e95SDavid du Colombier 
476f5736e95SDavid du Colombier 	bUseLandscape = pOptions->bUseLandscape;
477f5736e95SDavid du Colombier 	eEncoding = pOptions->eEncoding;
478f5736e95SDavid du Colombier 	eImageLevel = pOptions->eImageLevel;
479f5736e95SDavid du Colombier 
480f5736e95SDavid du Colombier 	if (pOptions->iPageHeight == INT_MAX) {
481f5736e95SDavid du Colombier 		lPageHeight = LONG_MAX;
482f5736e95SDavid du Colombier 	} else {
483f5736e95SDavid du Colombier 		lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight);
484f5736e95SDavid du Colombier 	}
485f5736e95SDavid du Colombier 	DBG_DEC(lPageHeight);
486f5736e95SDavid du Colombier 	if (pOptions->iPageWidth == INT_MAX) {
487f5736e95SDavid du Colombier 		lPageWidth = LONG_MAX;
488f5736e95SDavid du Colombier 	} else {
489f5736e95SDavid du Colombier 		lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth);
490f5736e95SDavid du Colombier 	}
491f5736e95SDavid du Colombier 	DBG_DEC(lPageWidth);
492*25b329d5SDavid du Colombier 	lFooterHeight = 0;
493*25b329d5SDavid du Colombier 	bInFtrSpace = FALSE;
494*25b329d5SDavid du Colombier 
495*25b329d5SDavid du Colombier 	tFontRefCurr = (drawfile_fontref)-1;
496f5736e95SDavid du Colombier 	usFontSizeCurr = 0;
497f5736e95SDavid du Colombier 	iFontColorCurr = -1;
498f5736e95SDavid du Colombier 	lYtopCurr = -1;
499f5736e95SDavid du Colombier 	iPageCount = 0;
500*25b329d5SDavid du Colombier 	iImageCount = 0;
501*25b329d5SDavid du Colombier 	iSectionIndex = 0;
502*25b329d5SDavid du Colombier 	bFirstInSection = TRUE;
503f5736e95SDavid du Colombier 	pDiag->lXleft = 0;
504f5736e95SDavid du Colombier 	pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
505f5736e95SDavid du Colombier 
506f5736e95SDavid du Colombier 	szCreator = szTask;
507f5736e95SDavid du Colombier 
508f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%!PS-Adobe-2.0\n");
509f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%Title: %s\n", szBasename(szFilename));
510f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%Creator: %s %s\n", szCreator, VERSIONSTRING);
511f5736e95SDavid du Colombier 	szTmp = getenv("LOGNAME");
512f5736e95SDavid du Colombier 	if (szTmp == NULL || szTmp[0] == '\0') {
513f5736e95SDavid du Colombier 		szTmp = getenv("USER");
514f5736e95SDavid du Colombier 		if (szTmp == NULL || szTmp[0] == '\0') {
515f5736e95SDavid du Colombier 			szTmp = "unknown";
516f5736e95SDavid du Colombier 		}
517f5736e95SDavid du Colombier 	}
518f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%For: %.50s\n", szTmp);
519f5736e95SDavid du Colombier 	errno = 0;
520f5736e95SDavid du Colombier 	tTime = time(NULL);
521f5736e95SDavid du Colombier 	if (tTime == (time_t)-1 && errno != 0) {
522f5736e95SDavid du Colombier 		szCreationDate = NULL;
523f5736e95SDavid du Colombier 	} else {
524f5736e95SDavid du Colombier 		szCreationDate = ctime(&tTime);
525f5736e95SDavid du Colombier 	}
526f5736e95SDavid du Colombier 	if (szCreationDate == NULL || szCreationDate[0] == '\0') {
527f5736e95SDavid du Colombier 		szCreationDate = "unknown\n";
528f5736e95SDavid du Colombier 	}
529f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%CreationDate: %s", szCreationDate);
530f5736e95SDavid du Colombier 	if (bUseLandscape) {
531f5736e95SDavid du Colombier 		fprintf(pOutFile, "%%%%Orientation: Landscape\n");
532f5736e95SDavid du Colombier 		fprintf(pOutFile, "%%%%BoundingBox: 0 0 %.0f %.0f\n",
533f5736e95SDavid du Colombier 				dDrawUnits2Points(lPageHeight),
534f5736e95SDavid du Colombier 				dDrawUnits2Points(lPageWidth));
535f5736e95SDavid du Colombier 	} else {
536f5736e95SDavid du Colombier 		fprintf(pOutFile, "%%%%Orientation: Portrait\n");
537f5736e95SDavid du Colombier 		fprintf(pOutFile, "%%%%BoundingBox: 0 0 %.0f %.0f\n",
538f5736e95SDavid du Colombier 				dDrawUnits2Points(lPageWidth),
539f5736e95SDavid du Colombier 				dDrawUnits2Points(lPageHeight));
540f5736e95SDavid du Colombier 	}
541f5736e95SDavid du Colombier } /* end of vProloguePS */
542f5736e95SDavid du Colombier 
543f5736e95SDavid du Colombier /*
544f5736e95SDavid du Colombier  * vEpiloguePS - clean up after everything is done
545f5736e95SDavid du Colombier  */
546f5736e95SDavid du Colombier void
vEpiloguePS(diagram_type * pDiag)547f5736e95SDavid du Colombier vEpiloguePS(diagram_type *pDiag)
548f5736e95SDavid du Colombier {
549f5736e95SDavid du Colombier 	fail(pDiag == NULL);
550f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
551f5736e95SDavid du Colombier 
552f5736e95SDavid du Colombier 	if (pDiag->lYtop < lPageHeight - PS_TOP_MARGIN) {
553*25b329d5SDavid du Colombier 		vAddFooter(pDiag);
554f5736e95SDavid du Colombier 		fprintf(pDiag->pOutFile, "showpage\n");
555f5736e95SDavid du Colombier 	}
556f5736e95SDavid du Colombier 	fprintf(pDiag->pOutFile, "%%%%Trailer\n");
557f5736e95SDavid du Colombier 	fprintf(pDiag->pOutFile, "%%%%Pages: %d\n", iPageCount);
558f5736e95SDavid du Colombier 	fprintf(pDiag->pOutFile, "%%%%EOF\n");
559f5736e95SDavid du Colombier 	szCreationDate = NULL;
560f5736e95SDavid du Colombier 	szCreator = NULL;
561f5736e95SDavid du Colombier } /* end of vEpiloguePS */
562f5736e95SDavid du Colombier 
563f5736e95SDavid du Colombier /*
564f5736e95SDavid du Colombier  * vPrintPalette - print a postscript palette
565f5736e95SDavid du Colombier  */
566f5736e95SDavid du Colombier static void
vPrintPalette(FILE * pOutFile,const imagedata_type * pImg)567f5736e95SDavid du Colombier vPrintPalette(FILE *pOutFile, const imagedata_type *pImg)
568f5736e95SDavid du Colombier {
569f5736e95SDavid du Colombier 	int	iIndex;
570f5736e95SDavid du Colombier 
571f5736e95SDavid du Colombier 	fail(pOutFile == NULL);
572f5736e95SDavid du Colombier 	fail(pImg == NULL);
573f5736e95SDavid du Colombier 	fail(pImg->iColorsUsed < 2);
574f5736e95SDavid du Colombier 	fail(pImg->iColorsUsed > 256);
575f5736e95SDavid du Colombier 
576f5736e95SDavid du Colombier 	fprintf(pOutFile, "[ /Indexed\n");
577f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t/Device%s %d\n",
578f5736e95SDavid du Colombier 		pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1);
579f5736e95SDavid du Colombier 	fprintf(pOutFile, "<");
580f5736e95SDavid du Colombier 	for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) {
581f5736e95SDavid du Colombier 		fprintf(pOutFile, "%02x",
582f5736e95SDavid du Colombier 				(unsigned int)pImg->aucPalette[iIndex][0]);
583f5736e95SDavid du Colombier 		if (pImg->bColorImage) {
584f5736e95SDavid du Colombier 			fprintf(pOutFile, "%02x%02x",
585f5736e95SDavid du Colombier 				(unsigned int)pImg->aucPalette[iIndex][1],
586f5736e95SDavid du Colombier 				(unsigned int)pImg->aucPalette[iIndex][2]);
587f5736e95SDavid du Colombier 		}
588f5736e95SDavid du Colombier 		if (iIndex % 8 == 7) {
589f5736e95SDavid du Colombier 			fprintf(pOutFile, "\n");
590f5736e95SDavid du Colombier 		} else {
591f5736e95SDavid du Colombier 			fprintf(pOutFile, " ");
592f5736e95SDavid du Colombier 		}
593f5736e95SDavid du Colombier 	}
594f5736e95SDavid du Colombier 	fprintf(pOutFile, ">\n");
595f5736e95SDavid du Colombier 	fprintf(pOutFile, "] setcolorspace\n");
596f5736e95SDavid du Colombier } /* end of vPrintPalette */
597f5736e95SDavid du Colombier 
598f5736e95SDavid du Colombier /*
599f5736e95SDavid du Colombier  * vImageProloguePS - perform the Encapsulated PostScript initialization
600f5736e95SDavid du Colombier  */
601f5736e95SDavid du Colombier void
vImageProloguePS(diagram_type * pDiag,const imagedata_type * pImg)602f5736e95SDavid du Colombier vImageProloguePS(diagram_type *pDiag, const imagedata_type *pImg)
603f5736e95SDavid du Colombier {
604f5736e95SDavid du Colombier 	FILE	*pOutFile;
605f5736e95SDavid du Colombier 
606f5736e95SDavid du Colombier 	fail(pDiag == NULL);
607f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
608f5736e95SDavid du Colombier 	fail(pImg == NULL);
609f5736e95SDavid du Colombier 
610f5736e95SDavid du Colombier 	if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
611f5736e95SDavid du Colombier 		return;
612f5736e95SDavid du Colombier 	}
613f5736e95SDavid du Colombier 
614f5736e95SDavid du Colombier 	fail(szCreationDate == NULL);
615f5736e95SDavid du Colombier 	fail(szCreator == NULL);
616f5736e95SDavid du Colombier 	fail(eImageLevel == level_no_images);
617f5736e95SDavid du Colombier 
618f5736e95SDavid du Colombier 	iImageCount++;
619f5736e95SDavid du Colombier 
620f5736e95SDavid du Colombier 	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
621f5736e95SDavid du Colombier 
622f5736e95SDavid du Colombier 	pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
623*25b329d5SDavid du Colombier 	vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
624f5736e95SDavid du Colombier 
625f5736e95SDavid du Colombier 	pOutFile = pDiag->pOutFile;
626f5736e95SDavid du Colombier 
627f5736e95SDavid du Colombier 	fprintf(pOutFile, "BeginEPSF\n");
628f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%BeginDocument: image%03d.eps\n", iImageCount);
629f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
630f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%Creator: %s %s\n", szCreator, VERSIONSTRING);
631f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%Title: Image %03d\n", iImageCount);
632f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%CreationDate: %s", szCreationDate);
633f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%BoundingBox: 0 0 %d %d\n",
634f5736e95SDavid du Colombier 				pImg->iHorSizeScaled, pImg->iVerSizeScaled);
635f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%DocumentData: Clean7Bit\n");
636f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%LanguageLevel: 2\n");
637f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%EndComments\n");
638f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%BeginProlog\n");
639f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%EndProlog\n");
640f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%Page: 1 1\n");
641f5736e95SDavid du Colombier 
642f5736e95SDavid du Colombier 	fprintf(pOutFile, "save\n");
643f5736e95SDavid du Colombier 
644f5736e95SDavid du Colombier 	switch (pImg->eImageType) {
645f5736e95SDavid du Colombier 	case imagetype_is_jpeg:
646f5736e95SDavid du Colombier 		fprintf(pOutFile, "/Data1 currentfile ");
647f5736e95SDavid du Colombier 		fprintf(pOutFile, "/ASCII85Decode filter def\n");
648f5736e95SDavid du Colombier 		fprintf(pOutFile, "/Data Data1 << ");
649f5736e95SDavid du Colombier 		fprintf(pOutFile, ">> /DCTDecode filter def\n");
650f5736e95SDavid du Colombier 		switch (pImg->iComponents) {
651f5736e95SDavid du Colombier 		case 1:
652f5736e95SDavid du Colombier 			fprintf(pOutFile, "/DeviceGray setcolorspace\n");
653f5736e95SDavid du Colombier 			break;
654f5736e95SDavid du Colombier 		case 3:
655f5736e95SDavid du Colombier 			fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
656f5736e95SDavid du Colombier 			break;
657f5736e95SDavid du Colombier 		case 4:
658f5736e95SDavid du Colombier 			fprintf(pOutFile, "/DeviceCMYK setcolorspace\n");
659f5736e95SDavid du Colombier 			break;
660f5736e95SDavid du Colombier 		default:
661f5736e95SDavid du Colombier 			DBG_DEC(pImg->iComponents);
662f5736e95SDavid du Colombier 			break;
663f5736e95SDavid du Colombier 		}
664f5736e95SDavid du Colombier 		break;
665f5736e95SDavid du Colombier 	case imagetype_is_png:
666f5736e95SDavid du Colombier 		if (eImageLevel == level_gs_special) {
667f5736e95SDavid du Colombier 			fprintf(pOutFile,
668f5736e95SDavid du Colombier 			"/Data2 currentfile /ASCII85Decode filter def\n");
669f5736e95SDavid du Colombier 			fprintf(pOutFile,
670f5736e95SDavid du Colombier 			"/Data1 Data2 << >> /FlateDecode filter def\n");
671f5736e95SDavid du Colombier 			fprintf(pOutFile, "/Data Data1 <<\n");
672f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Colors %d\n", pImg->iComponents);
673f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/BitsPerComponent %u\n",
674f5736e95SDavid du Colombier 						pImg->uiBitsPerComponent);
675f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Columns %d\n", pImg->iWidth);
676f5736e95SDavid du Colombier 			fprintf(pOutFile,
677f5736e95SDavid du Colombier 				">> /PNGPredictorDecode filter def\n");
678f5736e95SDavid du Colombier 		} else {
679f5736e95SDavid du Colombier 			fprintf(pOutFile,
680f5736e95SDavid du Colombier 			"/Data1 currentfile /ASCII85Decode filter def\n");
681f5736e95SDavid du Colombier 			fprintf(pOutFile,
682f5736e95SDavid du Colombier 			"/Data Data1 << >> /FlateDecode filter def\n");
683f5736e95SDavid du Colombier 		}
684*25b329d5SDavid du Colombier 		if (pImg->iComponents == 3 || pImg->iComponents == 4) {
685f5736e95SDavid du Colombier 			fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
686f5736e95SDavid du Colombier 		} else if (pImg->iColorsUsed > 0) {
687f5736e95SDavid du Colombier 			vPrintPalette(pOutFile, pImg);
688f5736e95SDavid du Colombier 		} else {
689f5736e95SDavid du Colombier 			fprintf(pOutFile, "/DeviceGray setcolorspace\n");
690f5736e95SDavid du Colombier 		}
691f5736e95SDavid du Colombier 		break;
692f5736e95SDavid du Colombier 	case imagetype_is_dib:
693f5736e95SDavid du Colombier 		fprintf(pOutFile, "/Data currentfile ");
694f5736e95SDavid du Colombier 		fprintf(pOutFile, "/ASCII85Decode filter def\n");
695f5736e95SDavid du Colombier 		if (pImg->uiBitsPerComponent <= 8) {
696f5736e95SDavid du Colombier 			vPrintPalette(pOutFile, pImg);
697f5736e95SDavid du Colombier 		} else {
698f5736e95SDavid du Colombier 			fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
699f5736e95SDavid du Colombier 		}
700f5736e95SDavid du Colombier 		break;
701f5736e95SDavid du Colombier 	default:
702f5736e95SDavid du Colombier 		fprintf(pOutFile, "/Data currentfile ");
703f5736e95SDavid du Colombier 		fprintf(pOutFile, "/ASCIIHexDecode filter def\n");
704f5736e95SDavid du Colombier 		fprintf(pOutFile, "/Device%s setcolorspace\n",
705f5736e95SDavid du Colombier 			pImg->bColorImage ? "RGB" : "Gray");
706f5736e95SDavid du Colombier 		break;
707f5736e95SDavid du Colombier 	}
708f5736e95SDavid du Colombier 
709f5736e95SDavid du Colombier 	/* Translate to lower left corner of image */
710f5736e95SDavid du Colombier 	fprintf(pOutFile, "%.2f %.2f translate\n",
711f5736e95SDavid du Colombier 			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
712f5736e95SDavid du Colombier 			dDrawUnits2Points(pDiag->lYtop));
713f5736e95SDavid du Colombier 
714f5736e95SDavid du Colombier 	fprintf(pOutFile, "%d %d scale\n",
715f5736e95SDavid du Colombier 				pImg->iHorSizeScaled, pImg->iVerSizeScaled);
716f5736e95SDavid du Colombier 
717f5736e95SDavid du Colombier 	fprintf(pOutFile, "{ <<\n");
718f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t/ImageType 1\n");
719f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t/Width %d\n", pImg->iWidth);
720f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t/Height %d\n", pImg->iHeight);
721f5736e95SDavid du Colombier 	if (pImg->eImageType == imagetype_is_dib) {
722f5736e95SDavid du Colombier 		/* Scanning from left to right and bottom to top */
723f5736e95SDavid du Colombier 		fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 0 ]\n",
724f5736e95SDavid du Colombier 			pImg->iWidth, pImg->iHeight);
725f5736e95SDavid du Colombier 	} else {
726f5736e95SDavid du Colombier 		/* Scanning from left to right and top to bottom */
727f5736e95SDavid du Colombier 		fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 %d ]\n",
728f5736e95SDavid du Colombier 			pImg->iWidth, -pImg->iHeight, pImg->iHeight);
729f5736e95SDavid du Colombier 	}
730f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t/DataSource Data\n");
731f5736e95SDavid du Colombier 
732f5736e95SDavid du Colombier 	switch (pImg->eImageType) {
733f5736e95SDavid du Colombier 	case imagetype_is_jpeg:
734f5736e95SDavid du Colombier 		fprintf(pOutFile, "\t/BitsPerComponent 8\n");
735f5736e95SDavid du Colombier 		switch (pImg->iComponents) {
736f5736e95SDavid du Colombier 		case 1:
737f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1]\n");
738f5736e95SDavid du Colombier 			break;
739f5736e95SDavid du Colombier 		case 3:
740f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
741f5736e95SDavid du Colombier 			break;
742f5736e95SDavid du Colombier 		case 4:
743f5736e95SDavid du Colombier 			if (pImg->bAdobe) {
744f5736e95SDavid du Colombier 				/*
745f5736e95SDavid du Colombier 				 * Adobe-conforming CMYK file
746f5736e95SDavid du Colombier 				 * applying workaround for color inversion
747f5736e95SDavid du Colombier 				 */
748f5736e95SDavid du Colombier 				fprintf(pOutFile,
749f5736e95SDavid du Colombier 					"\t/Decode [1 0 1 0 1 0 1 0]\n");
750f5736e95SDavid du Colombier 			} else {
751f5736e95SDavid du Colombier 				fprintf(pOutFile,
752f5736e95SDavid du Colombier 					"\t/Decode [0 1 0 1 0 1 0 1]\n");
753f5736e95SDavid du Colombier 			}
754f5736e95SDavid du Colombier 			break;
755f5736e95SDavid du Colombier 		default:
756f5736e95SDavid du Colombier 			DBG_DEC(pImg->iComponents);
757f5736e95SDavid du Colombier 			break;
758f5736e95SDavid du Colombier 		}
759f5736e95SDavid du Colombier 		break;
760f5736e95SDavid du Colombier 	case imagetype_is_png:
761f5736e95SDavid du Colombier 		if (pImg->iComponents == 3) {
762f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/BitsPerComponent 8\n");
763f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
764f5736e95SDavid du Colombier 		} else if (pImg->iColorsUsed > 0) {
765f5736e95SDavid du Colombier 			fail(pImg->uiBitsPerComponent > 8);
766f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/BitsPerComponent %u\n",
767f5736e95SDavid du Colombier 					pImg->uiBitsPerComponent);
768f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 %d]\n",
769f5736e95SDavid du Colombier 					(1 << pImg->uiBitsPerComponent) - 1);
770f5736e95SDavid du Colombier 		} else {
771f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/BitsPerComponent 8\n");
772f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1]\n");
773f5736e95SDavid du Colombier 		}
774f5736e95SDavid du Colombier 		break;
775f5736e95SDavid du Colombier 	case imagetype_is_dib:
776f5736e95SDavid du Colombier 		fprintf(pOutFile, "\t/BitsPerComponent 8\n");
777f5736e95SDavid du Colombier 		if (pImg->uiBitsPerComponent <= 8) {
778f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 255]\n");
779f5736e95SDavid du Colombier 		} else {
780f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
781f5736e95SDavid du Colombier 		}
782f5736e95SDavid du Colombier 		break;
783f5736e95SDavid du Colombier 	default:
784f5736e95SDavid du Colombier 		fprintf(pOutFile, "\t/BitsPerComponent 8\n");
785f5736e95SDavid du Colombier 		if (pImg->bColorImage) {
786f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
787f5736e95SDavid du Colombier 		} else {
788f5736e95SDavid du Colombier 			fprintf(pOutFile, "\t/Decode [0 1]\n");
789f5736e95SDavid du Colombier 		}
790f5736e95SDavid du Colombier 		break;
791f5736e95SDavid du Colombier 	}
792f5736e95SDavid du Colombier 
793f5736e95SDavid du Colombier 	fprintf(pOutFile, "  >> image\n");
794f5736e95SDavid du Colombier 	fprintf(pOutFile, "  Data closefile\n");
795f5736e95SDavid du Colombier 	fprintf(pOutFile, "  showpage\n");
796f5736e95SDavid du Colombier 	fprintf(pOutFile, "  restore\n");
797f5736e95SDavid du Colombier 	fprintf(pOutFile, "} exec\n");
798f5736e95SDavid du Colombier } /* end of vImageProloguePS */
799f5736e95SDavid du Colombier 
800f5736e95SDavid du Colombier /*
801f5736e95SDavid du Colombier  * vImageEpiloguePS - clean up after Encapsulated PostScript
802f5736e95SDavid du Colombier  */
803f5736e95SDavid du Colombier void
vImageEpiloguePS(diagram_type * pDiag)804f5736e95SDavid du Colombier vImageEpiloguePS(diagram_type *pDiag)
805f5736e95SDavid du Colombier {
806f5736e95SDavid du Colombier 	FILE	*pOutFile;
807f5736e95SDavid du Colombier 
808f5736e95SDavid du Colombier 	fail(pDiag == NULL);
809f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
810f5736e95SDavid du Colombier 
811f5736e95SDavid du Colombier 	pOutFile = pDiag->pOutFile;
812f5736e95SDavid du Colombier 
813f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%EOF\n");
814f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%EndDocument\n");
815f5736e95SDavid du Colombier 	fprintf(pOutFile, "EndEPSF\n");
816f5736e95SDavid du Colombier 
817f5736e95SDavid du Colombier 	pDiag->lXleft = 0;
818f5736e95SDavid du Colombier } /* end of vImageEpiloguePS */
819f5736e95SDavid du Colombier 
820f5736e95SDavid du Colombier /*
821f5736e95SDavid du Colombier  * bAddDummyImagePS - add a dummy image
822f5736e95SDavid du Colombier  *
823f5736e95SDavid du Colombier  * return TRUE when successful, otherwise FALSE
824f5736e95SDavid du Colombier  */
825f5736e95SDavid du Colombier BOOL
bAddDummyImagePS(diagram_type * pDiag,const imagedata_type * pImg)826f5736e95SDavid du Colombier bAddDummyImagePS(diagram_type *pDiag, const imagedata_type *pImg)
827f5736e95SDavid du Colombier {
828f5736e95SDavid du Colombier 	FILE	*pOutFile;
829f5736e95SDavid du Colombier 
830f5736e95SDavid du Colombier 	fail(pDiag == NULL);
831f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
832f5736e95SDavid du Colombier 	fail(pImg == NULL);
833f5736e95SDavid du Colombier 
834f5736e95SDavid du Colombier 	if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
835f5736e95SDavid du Colombier 		return FALSE;
836f5736e95SDavid du Colombier 	}
837f5736e95SDavid du Colombier 
838f5736e95SDavid du Colombier 	iImageCount++;
839f5736e95SDavid du Colombier 
840f5736e95SDavid du Colombier 	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
841f5736e95SDavid du Colombier 
842f5736e95SDavid du Colombier 	pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
843*25b329d5SDavid du Colombier 	vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
844f5736e95SDavid du Colombier 
845f5736e95SDavid du Colombier 	pOutFile = pDiag->pOutFile;
846f5736e95SDavid du Colombier 
847f5736e95SDavid du Colombier 	fprintf(pOutFile, "gsave %% Image %03d\n", iImageCount);
848f5736e95SDavid du Colombier 	fprintf(pOutFile, "\tnewpath\n");
849f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t%.2f %.2f moveto\n",
850f5736e95SDavid du Colombier 			dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
851f5736e95SDavid du Colombier 			dDrawUnits2Points(pDiag->lYtop));
852f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t1.0 setlinewidth\n");
853f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t0.3 setgray\n");
854f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t0 %d rlineto\n", pImg->iVerSizeScaled);
855f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t%d 0 rlineto\n", pImg->iHorSizeScaled);
856f5736e95SDavid du Colombier 	fprintf(pOutFile, "\t0 %d rlineto\n", -pImg->iVerSizeScaled);
857f5736e95SDavid du Colombier 	fprintf(pOutFile, "\tclosepath\n");
858f5736e95SDavid du Colombier 	fprintf(pOutFile, "\tstroke\n");
859f5736e95SDavid du Colombier 	fprintf(pOutFile, "grestore\n");
860f5736e95SDavid du Colombier 
861f5736e95SDavid du Colombier 	pDiag->lXleft = 0;
862f5736e95SDavid du Colombier 
863f5736e95SDavid du Colombier 	return TRUE;
864f5736e95SDavid du Colombier } /* end of bAddDummyImagePS */
865f5736e95SDavid du Colombier 
866f5736e95SDavid du Colombier /*
867f5736e95SDavid du Colombier  * vAddFontsPS - add the list of fonts and complete the prologue
868f5736e95SDavid du Colombier  */
869f5736e95SDavid du Colombier void
vAddFontsPS(diagram_type * pDiag)870f5736e95SDavid du Colombier vAddFontsPS(diagram_type *pDiag)
871f5736e95SDavid du Colombier {
872f5736e95SDavid du Colombier 	FILE	*pOutFile;
873f5736e95SDavid du Colombier 	const font_table_type *pTmp, *pTmp2;
874f5736e95SDavid du Colombier 	size_t	tIndex;
875*25b329d5SDavid du Colombier 	int	iLineLen, iOurFontnameLen;
876f5736e95SDavid du Colombier 	BOOL	bFound;
877f5736e95SDavid du Colombier 
878f5736e95SDavid du Colombier 	fail(pDiag == NULL);
879f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
880f5736e95SDavid du Colombier 
881f5736e95SDavid du Colombier 	pOutFile = pDiag->pOutFile;
882f5736e95SDavid du Colombier 	iLineLen = fprintf(pOutFile, "%%%%DocumentFonts:");
883f5736e95SDavid du Colombier 
884f5736e95SDavid du Colombier 	if (tGetFontTableLength() == 0) {
885f5736e95SDavid du Colombier 		iLineLen += fprintf(pOutFile, " Courier");
886f5736e95SDavid du Colombier 	} else {
887f5736e95SDavid du Colombier 		pTmp = NULL;
888f5736e95SDavid du Colombier 		while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {
889f5736e95SDavid du Colombier 			/* Print the document fonts */
890f5736e95SDavid du Colombier 			bFound = FALSE;
891f5736e95SDavid du Colombier 			pTmp2 = NULL;
892f5736e95SDavid du Colombier 			while ((pTmp2 = pGetNextFontTableRecord(pTmp2))
893f5736e95SDavid du Colombier 					!= NULL && pTmp2 < pTmp) {
894f5736e95SDavid du Colombier 				bFound = STREQ(pTmp2->szOurFontname,
895f5736e95SDavid du Colombier 						pTmp->szOurFontname);
896f5736e95SDavid du Colombier 				if (bFound) {
897f5736e95SDavid du Colombier 					break;
898f5736e95SDavid du Colombier 				}
899f5736e95SDavid du Colombier 			}
900*25b329d5SDavid du Colombier 			iOurFontnameLen = (int)strlen(pTmp->szOurFontname);
901*25b329d5SDavid du Colombier 			if (bFound || iOurFontnameLen <= 0) {
902f5736e95SDavid du Colombier 				continue;
903f5736e95SDavid du Colombier 			}
904*25b329d5SDavid du Colombier 			if (iLineLen + iOurFontnameLen > 76) {
905f5736e95SDavid du Colombier 				fprintf(pOutFile, "\n%%%%+");
906f5736e95SDavid du Colombier 				iLineLen = 3;
907f5736e95SDavid du Colombier 			}
908f5736e95SDavid du Colombier 			iLineLen += fprintf(pOutFile,
909f5736e95SDavid du Colombier 					" %s", pTmp->szOurFontname);
910f5736e95SDavid du Colombier 		}
911f5736e95SDavid du Colombier 	}
912f5736e95SDavid du Colombier 	fprintf(pOutFile, "\n");
913f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%Pages: (atend)\n");
914f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%EndComments\n");
915f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%BeginProlog\n");
916f5736e95SDavid du Colombier 
917f5736e95SDavid du Colombier 	switch (eEncoding) {
918*25b329d5SDavid du Colombier 	case encoding_latin_1:
919f5736e95SDavid du Colombier 		for (tIndex = 0;
920f5736e95SDavid du Colombier 		     tIndex < elementsof(iso_8859_1_data);
921f5736e95SDavid du Colombier 		     tIndex++) {
922f5736e95SDavid du Colombier 			fprintf(pOutFile, "%s\n", iso_8859_1_data[tIndex]);
923f5736e95SDavid du Colombier 		}
924f5736e95SDavid du Colombier 		fprintf(pOutFile, "\n");
925f5736e95SDavid du Colombier 		for (tIndex = 0;
926f5736e95SDavid du Colombier 		     tIndex < elementsof(iso_8859_x_func);
927f5736e95SDavid du Colombier 		     tIndex++) {
928f5736e95SDavid du Colombier 			fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
929f5736e95SDavid du Colombier 		}
930f5736e95SDavid du Colombier 		break;
931*25b329d5SDavid du Colombier 	case encoding_latin_2:
932f5736e95SDavid du Colombier 		for (tIndex = 0;
933f5736e95SDavid du Colombier 		     tIndex < elementsof(iso_8859_2_data);
934f5736e95SDavid du Colombier 		     tIndex++) {
935f5736e95SDavid du Colombier 			fprintf(pOutFile, "%s\n", iso_8859_2_data[tIndex]);
936f5736e95SDavid du Colombier 		}
937f5736e95SDavid du Colombier 		fprintf(pOutFile, "\n");
938f5736e95SDavid du Colombier 		for (tIndex = 0;
939f5736e95SDavid du Colombier 		     tIndex < elementsof(iso_8859_x_func);
940f5736e95SDavid du Colombier 		     tIndex++) {
941f5736e95SDavid du Colombier 			fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
942f5736e95SDavid du Colombier 		}
943f5736e95SDavid du Colombier 		break;
944*25b329d5SDavid du Colombier 	case encoding_cyrillic:
945*25b329d5SDavid du Colombier 		for (tIndex = 0;
946*25b329d5SDavid du Colombier 		     tIndex < elementsof(iso_8859_5_data);
947*25b329d5SDavid du Colombier 		     tIndex++) {
948*25b329d5SDavid du Colombier 			fprintf(pOutFile, "%s\n", iso_8859_5_data[tIndex]);
949*25b329d5SDavid du Colombier 		}
950*25b329d5SDavid du Colombier 		fprintf(pOutFile, "\n");
951*25b329d5SDavid du Colombier 		for (tIndex = 0;
952*25b329d5SDavid du Colombier 		     tIndex < elementsof(iso_8859_x_func);
953*25b329d5SDavid du Colombier 		     tIndex++) {
954*25b329d5SDavid du Colombier 			fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
955*25b329d5SDavid du Colombier 		}
956*25b329d5SDavid du Colombier 		break;
957*25b329d5SDavid du Colombier 	case encoding_utf_8:
958f5736e95SDavid du Colombier 		werr(1,
959f5736e95SDavid du Colombier 		"The combination PostScript and UTF-8 is not supported");
960f5736e95SDavid du Colombier 		break;
961f5736e95SDavid du Colombier 	default:
962f5736e95SDavid du Colombier 		DBG_DEC(eEncoding);
963f5736e95SDavid du Colombier 		break;
964f5736e95SDavid du Colombier 	}
965f5736e95SDavid du Colombier 
966f5736e95SDavid du Colombier 	/* The rest of the functions */
967f5736e95SDavid du Colombier 	for (tIndex = 0; tIndex < elementsof(misc_func); tIndex++) {
968f5736e95SDavid du Colombier 		fprintf(pOutFile, "%s\n", misc_func[tIndex]);
969f5736e95SDavid du Colombier 	}
970f5736e95SDavid du Colombier 	fprintf(pOutFile, "%%%%EndProlog\n");
971f5736e95SDavid du Colombier 	iPageCount = 1;
972f5736e95SDavid du Colombier 	fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount);
973f5736e95SDavid du Colombier 	vAddPageSetup(pDiag->pOutFile);
974*25b329d5SDavid du Colombier 	vAddHeader(pDiag);
975f5736e95SDavid du Colombier } /* end of vAddFontsPS */
976f5736e95SDavid du Colombier 
977f5736e95SDavid du Colombier /*
978f5736e95SDavid du Colombier  * vPrintPS - print a PostScript string
979f5736e95SDavid du Colombier  */
980f5736e95SDavid du Colombier static void
vPrintPS(FILE * pFile,const char * szString,size_t tStringLength,USHORT usFontstyle)981f5736e95SDavid du Colombier vPrintPS(FILE *pFile, const char *szString, size_t tStringLength,
982f5736e95SDavid du Colombier 		USHORT usFontstyle)
983f5736e95SDavid du Colombier {
984f5736e95SDavid du Colombier 	double		dSuperscriptMove, dSubscriptMove;
985f5736e95SDavid du Colombier 	const UCHAR	*ucBytes;
986f5736e95SDavid du Colombier 	size_t		tCount;
987f5736e95SDavid du Colombier 
988f5736e95SDavid du Colombier 	fail(szString == NULL);
989f5736e95SDavid du Colombier 
990f5736e95SDavid du Colombier 	if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
991f5736e95SDavid du Colombier 		return;
992f5736e95SDavid du Colombier 	}
993f5736e95SDavid du Colombier 	DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr);
994f5736e95SDavid du Colombier 
995f5736e95SDavid du Colombier 	dSuperscriptMove = 0.0;
996f5736e95SDavid du Colombier 	dSubscriptMove = 0.0;
997f5736e95SDavid du Colombier 
998f5736e95SDavid du Colombier 	/* Up for superscript */
999f5736e95SDavid du Colombier 	if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) {
1000f5736e95SDavid du Colombier 		dSuperscriptMove = (double)((usFontSizeCurr + 1) / 2) * 0.375;
1001f5736e95SDavid du Colombier 		fprintf(pFile, "0 %.2f rmoveto\n", dSuperscriptMove);
1002f5736e95SDavid du Colombier 	}
1003f5736e95SDavid du Colombier 
1004f5736e95SDavid du Colombier 	/* Down for subscript */
1005f5736e95SDavid du Colombier 	if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
1006f5736e95SDavid du Colombier 		dSubscriptMove = (double)usFontSizeCurr * 0.125;
1007f5736e95SDavid du Colombier 		fprintf(pFile, "0 %.2f rmoveto\n", -dSubscriptMove);
1008f5736e95SDavid du Colombier 	}
1009f5736e95SDavid du Colombier 
1010f5736e95SDavid du Colombier 	/* Generate and print the PostScript output */
1011f5736e95SDavid du Colombier 	ucBytes = (UCHAR *)szString;
1012f5736e95SDavid du Colombier 	(void)putc('(', pFile);
1013f5736e95SDavid du Colombier 	for (tCount = 0; tCount < tStringLength ; tCount++) {
1014f5736e95SDavid du Colombier 		switch (ucBytes[tCount]) {
1015f5736e95SDavid du Colombier 		case '(':
1016f5736e95SDavid du Colombier 		case ')':
1017f5736e95SDavid du Colombier 		case '\\':
1018f5736e95SDavid du Colombier 			(void)putc('\\', pFile);
1019f5736e95SDavid du Colombier 			(void)putc(szString[tCount], pFile);
1020f5736e95SDavid du Colombier 			break;
1021f5736e95SDavid du Colombier 		default:
1022f5736e95SDavid du Colombier 			if (ucBytes[tCount] < 0x20 ||
1023f5736e95SDavid du Colombier 			    (ucBytes[tCount] >= 0x7f &&
1024f5736e95SDavid du Colombier 			     ucBytes[tCount] < 0x8c)) {
1025f5736e95SDavid du Colombier 				DBG_HEX(ucBytes[tCount]);
1026f5736e95SDavid du Colombier 				(void)putc(' ', pFile);
1027f5736e95SDavid du Colombier 			} else if (ucBytes[tCount] >= 0x80) {
1028f5736e95SDavid du Colombier 				fprintf(pFile, "\\%03o", (UINT)ucBytes[tCount]);
1029f5736e95SDavid du Colombier 			} else {
1030f5736e95SDavid du Colombier 				(void)putc(szString[tCount], pFile);
1031f5736e95SDavid du Colombier 			}
1032f5736e95SDavid du Colombier 			break;
1033f5736e95SDavid du Colombier 		}
1034f5736e95SDavid du Colombier 	}
1035f5736e95SDavid du Colombier 	fprintf(pFile, ") ");
1036f5736e95SDavid du Colombier 	if ((bIsStrike(usFontstyle) || bIsMarkDel(usFontstyle)) &&
1037f5736e95SDavid du Colombier 			usFontSizeCurr != 0) {
1038f5736e95SDavid du Colombier 		fprintf(pFile, "%.2f %.2f LineShow\n",
1039f5736e95SDavid du Colombier 			(double)usFontSizeCurr * 0.02,
1040f5736e95SDavid du Colombier 			(double)usFontSizeCurr * 0.12);
1041f5736e95SDavid du Colombier 	} else if (bIsUnderline(usFontstyle) && usFontSizeCurr != 0) {
1042f5736e95SDavid du Colombier 		fprintf(pFile, "%.2f %.2f LineShow\n",
1043f5736e95SDavid du Colombier 			(double)usFontSizeCurr * 0.02,
1044f5736e95SDavid du Colombier 			(double)usFontSizeCurr * -0.06);
1045f5736e95SDavid du Colombier 	} else {
1046f5736e95SDavid du Colombier 		fprintf(pFile, "show\n");
1047f5736e95SDavid du Colombier 	}
1048f5736e95SDavid du Colombier 
1049f5736e95SDavid du Colombier 	/* Undo the superscript move */
1050f5736e95SDavid du Colombier 	if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) {
1051f5736e95SDavid du Colombier 		fprintf(pFile, "0 %.2f rmoveto\n", -dSuperscriptMove);
1052f5736e95SDavid du Colombier 	}
1053f5736e95SDavid du Colombier 
1054f5736e95SDavid du Colombier 	/* Undo the subscript move */
1055f5736e95SDavid du Colombier 	if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
1056f5736e95SDavid du Colombier 		fprintf(pFile, "0 %.2f rmoveto\n", dSubscriptMove);
1057f5736e95SDavid du Colombier 	}
1058f5736e95SDavid du Colombier } /* end of vPrintPS */
1059f5736e95SDavid du Colombier 
1060f5736e95SDavid du Colombier /*
1061f5736e95SDavid du Colombier  * vSetColor - move to the specified color
1062f5736e95SDavid du Colombier  */
1063f5736e95SDavid du Colombier static void
vSetColor(FILE * pFile,UCHAR ucFontColor)1064f5736e95SDavid du Colombier vSetColor(FILE *pFile, UCHAR ucFontColor)
1065f5736e95SDavid du Colombier {
1066f5736e95SDavid du Colombier 	ULONG	ulTmp, ulRed, ulGreen, ulBlue;
1067f5736e95SDavid du Colombier 
1068f5736e95SDavid du Colombier 	ulTmp = ulColor2Color(ucFontColor);
1069f5736e95SDavid du Colombier 	ulRed   = (ulTmp & 0x0000ff00) >> 8;
1070f5736e95SDavid du Colombier 	ulGreen = (ulTmp & 0x00ff0000) >> 16;
1071f5736e95SDavid du Colombier 	ulBlue  = (ulTmp & 0xff000000) >> 24;
1072f5736e95SDavid du Colombier 	fprintf(pFile, "%.3f %.3f %.3f setrgbcolor\n",
1073f5736e95SDavid du Colombier 				ulRed / 255.0, ulGreen / 255.0, ulBlue / 255.0);
1074f5736e95SDavid du Colombier } /* end of vSetColor */
1075f5736e95SDavid du Colombier 
1076f5736e95SDavid du Colombier /*
1077f5736e95SDavid du Colombier  * vMove2NextLinePS - move to the next line
1078f5736e95SDavid du Colombier  */
1079f5736e95SDavid du Colombier void
vMove2NextLinePS(diagram_type * pDiag,USHORT usFontSize)1080f5736e95SDavid du Colombier vMove2NextLinePS(diagram_type *pDiag, USHORT usFontSize)
1081f5736e95SDavid du Colombier {
1082f5736e95SDavid du Colombier 	fail(pDiag == NULL);
1083f5736e95SDavid du Colombier 	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
1084f5736e95SDavid du Colombier 
1085f5736e95SDavid du Colombier 	pDiag->lYtop -= lComputeLeading(usFontSize);
1086f5736e95SDavid du Colombier } /* end of vMove2NextLinePS */
1087f5736e95SDavid du Colombier 
1088f5736e95SDavid du Colombier /*
1089f5736e95SDavid du Colombier  * vSubstringPS - print a sub string
1090f5736e95SDavid du Colombier  */
1091f5736e95SDavid du Colombier void
vSubstringPS(diagram_type * pDiag,char * szString,size_t tStringLength,long lStringWidth,UCHAR ucFontColor,USHORT usFontstyle,drawfile_fontref tFontRef,USHORT usFontSize,USHORT usMaxFontSize)1092f5736e95SDavid du Colombier vSubstringPS(diagram_type *pDiag,
1093f5736e95SDavid du Colombier 	char *szString, size_t tStringLength, long lStringWidth,
1094*25b329d5SDavid du Colombier 	UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
1095f5736e95SDavid du Colombier 	USHORT usFontSize, USHORT usMaxFontSize)
1096f5736e95SDavid du Colombier {
1097f5736e95SDavid du Colombier 	const char	*szOurFontname;
1098f5736e95SDavid du Colombier 
1099f5736e95SDavid du Colombier 	fail(pDiag == NULL || szString == NULL);
1100f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
1101f5736e95SDavid du Colombier 	fail(pDiag->lXleft < 0);
1102f5736e95SDavid du Colombier 	fail(tStringLength != strlen(szString));
1103f5736e95SDavid du Colombier 	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
1104f5736e95SDavid du Colombier 	fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE);
1105f5736e95SDavid du Colombier 	fail(usFontSize > usMaxFontSize);
1106f5736e95SDavid du Colombier 
1107f5736e95SDavid du Colombier 	if (szString[0] == '\0' || tStringLength == 0) {
1108f5736e95SDavid du Colombier 		return;
1109f5736e95SDavid du Colombier 	}
1110f5736e95SDavid du Colombier 
1111f5736e95SDavid du Colombier 	if (tFontRef != tFontRefCurr || usFontSize != usFontSizeCurr) {
1112f5736e95SDavid du Colombier 		szOurFontname = szGetFontname(tFontRef);
1113f5736e95SDavid du Colombier 		fail(szOurFontname == NULL);
1114f5736e95SDavid du Colombier 		fprintf(pDiag->pOutFile,
1115f5736e95SDavid du Colombier 			"%.1f /%s /%s-ISO-8859-x ChgFnt\n",
1116f5736e95SDavid du Colombier 			(double)usFontSize / 2.0,
1117f5736e95SDavid du Colombier 			szOurFontname, szOurFontname);
1118f5736e95SDavid du Colombier 		tFontRefCurr = tFontRef;
1119f5736e95SDavid du Colombier 		usFontSizeCurr = usFontSize;
1120f5736e95SDavid du Colombier 	}
1121f5736e95SDavid du Colombier 	if ((int)ucFontColor != iFontColorCurr) {
1122f5736e95SDavid du Colombier 		vSetColor(pDiag->pOutFile, ucFontColor);
1123f5736e95SDavid du Colombier 		iFontColorCurr = (int)ucFontColor;
1124f5736e95SDavid du Colombier 	}
1125*25b329d5SDavid du Colombier 	vMoveTo(pDiag, lComputeLeading(usMaxFontSize));
1126f5736e95SDavid du Colombier 	vPrintPS(pDiag->pOutFile, szString, tStringLength, usFontstyle);
1127f5736e95SDavid du Colombier 	pDiag->lXleft += lStringWidth;
1128f5736e95SDavid du Colombier } /* end of vSubstringPS */
1129f5736e95SDavid du Colombier 
1130f5736e95SDavid du Colombier /*
1131f5736e95SDavid du Colombier  * Create an start of paragraph by moving the y-top mark
1132f5736e95SDavid du Colombier  */
1133f5736e95SDavid du Colombier void
vStartOfParagraphPS(diagram_type * pDiag,long lBeforeIndentation)1134f5736e95SDavid du Colombier vStartOfParagraphPS(diagram_type *pDiag, long lBeforeIndentation)
1135f5736e95SDavid du Colombier {
1136f5736e95SDavid du Colombier 	fail(pDiag == NULL);
1137f5736e95SDavid du Colombier 	fail(lBeforeIndentation < 0);
1138f5736e95SDavid du Colombier 
1139f5736e95SDavid du Colombier 	pDiag->lXleft = 0;
1140f5736e95SDavid du Colombier 	pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation);
1141f5736e95SDavid du Colombier } /* end of vStartOfParagraphPS */
1142f5736e95SDavid du Colombier 
1143f5736e95SDavid du Colombier /*
1144f5736e95SDavid du Colombier  * Create an end of paragraph by moving the y-top mark
1145f5736e95SDavid du Colombier  */
1146f5736e95SDavid du Colombier void
vEndOfParagraphPS(diagram_type * pDiag,USHORT usFontSize,long lAfterIndentation)1147f5736e95SDavid du Colombier vEndOfParagraphPS(diagram_type *pDiag,
1148*25b329d5SDavid du Colombier 	USHORT usFontSize, long lAfterIndentation)
1149f5736e95SDavid du Colombier {
1150f5736e95SDavid du Colombier 	fail(pDiag == NULL);
1151f5736e95SDavid du Colombier 	fail(pDiag->pOutFile == NULL);
1152f5736e95SDavid du Colombier 	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
1153f5736e95SDavid du Colombier 	fail(lAfterIndentation < 0);
1154f5736e95SDavid du Colombier 
1155f5736e95SDavid du Colombier 	if (pDiag->lXleft > 0) {
1156f5736e95SDavid du Colombier 		/* To the start of the line */
1157*25b329d5SDavid du Colombier 		vMove2NextLinePS(pDiag, usFontSize);
1158f5736e95SDavid du Colombier 	}
1159f5736e95SDavid du Colombier 
1160f5736e95SDavid du Colombier 	pDiag->lXleft = 0;
1161f5736e95SDavid du Colombier 	pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
1162f5736e95SDavid du Colombier } /* end of vEndOfParagraphPS */
1163f5736e95SDavid du Colombier 
1164f5736e95SDavid du Colombier /*
1165f5736e95SDavid du Colombier  * Create an end of page
1166f5736e95SDavid du Colombier  */
1167f5736e95SDavid du Colombier void
vEndOfPagePS(diagram_type * pDiag,BOOL bNewSection)1168*25b329d5SDavid du Colombier vEndOfPagePS(diagram_type *pDiag, BOOL bNewSection)
1169f5736e95SDavid du Colombier {
1170*25b329d5SDavid du Colombier 	vMove2NextPage(pDiag, bNewSection);
1171f5736e95SDavid du Colombier } /* end of vEndOfPagePS */
1172