1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/ps.c,v 1.16 2011/05/16 16:21:59 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_PS_C_
22 
23 #include "tgifdefs.h"
24 
25 #include "file.e"
26 #include "msg.e"
27 #include "ps.e"
28 #include "raster.e"
29 #include "util.e"
30 
31 #define DEF_PS_DICT_COUNT 3
32 
33 int preDumpSetup=FALSE;
34 int needsTgifOrigCTM=TRUE;
35 int psUseShortHand=FALSE;
36 
37 char **gPsCmd=NULL;
38 
39 static int psDictCount=DEF_PS_DICT_COUNT;
40 
41 static int psUsePSAdobe=TRUE;
42 static int psUseMinRadius=FALSE;
43 static int psUseEllipse=FALSE;
44 static int psUseArrow=FALSE;
45 static int psUseArc=FALSE;
46 static int psUsePattern=FALSE;
47 static int psUseBWPattern=FALSE;
48 static int psUseColorImage=FALSE;
49 static int psUseColorPattern=FALSE;
50 static int psUseCenterText=FALSE;
51 static int psUseRightText=FALSE;
52 static int psUseMiniLines=FALSE;
53 static int psUseReencode=FALSE;
54 static int psUseReencodeFF8=FALSE;
55 
56 #ifdef _PS_USE_EUC_FONT
57 static int psUseEucFont=FALSE;
58 #endif /* _PS_USE_EUC_FONT */
59 
PSUsePSAdobe()60 void PSUsePSAdobe()
61 {
62    if (preDumpSetup && !psUsePSAdobe) {
63       psUsePSAdobe = FALSE;
64    }
65 }
66 
PSUseMinRadius()67 void PSUseMinRadius()
68 {
69    if (preDumpSetup && !psUseMinRadius) {
70       psUseMinRadius = TRUE;
71       psDictCount++;
72    }
73 }
74 
PSUseEllipse()75 void PSUseEllipse()
76 {
77    if (preDumpSetup && !psUseEllipse) {
78       psUseEllipse = TRUE;
79       psDictCount += 2;
80    }
81 }
82 
PSUseArrow()83 void PSUseArrow()
84 {
85    if (preDumpSetup && !psUseArrow) {
86       psUseArrow = TRUE;
87       psDictCount += 2;
88    }
89 }
90 
PSUseArc()91 void PSUseArc()
92 {
93    if (preDumpSetup && !psUseArc) {
94       psUseArc = TRUE;
95       psDictCount += 3;
96    }
97 }
98 
99 static
PSUsePattern()100 void PSUsePattern()
101 {
102    if (preDumpSetup && !psUsePattern) {
103       psUsePattern = TRUE;
104       psDictCount += 29;
105    }
106 }
107 
PSUseBWPattern()108 void PSUseBWPattern()
109 {
110    if (preDumpSetup && !psUseBWPattern) {
111       PSUsePattern();
112       psUseBWPattern = TRUE;
113       psDictCount += 5;
114    }
115 }
116 
PSUseColorImage()117 void PSUseColorImage()
118 {
119    if (preDumpSetup && !psUseColorImage) {
120       psUseColorImage = TRUE;
121       psDictCount += 13;
122    }
123 }
124 
PSUseColorPattern()125 void PSUseColorPattern()
126 {
127    if (preDumpSetup && !psUseColorPattern) {
128       PSUsePattern();
129       psUseColorPattern = TRUE;
130       psDictCount += 4;
131    }
132 }
133 
PSUseCenterText()134 void PSUseCenterText()
135 {
136    if (preDumpSetup && !psUseCenterText) {
137       psUseCenterText = TRUE;
138       psDictCount += 1;
139    }
140 }
141 
PSUseRightText()142 void PSUseRightText()
143 {
144    if (preDumpSetup && !psUseRightText) {
145       psUseRightText = TRUE;
146       psDictCount += 1;
147    }
148 }
149 
PSUseMiniLines()150 void PSUseMiniLines()
151 {
152    if (preDumpSetup && !psUseMiniLines) {
153       psUseMiniLines = TRUE;
154       psDictCount += 3;
155    }
156 }
157 
158 typedef struct ReEncodeRec {
159    char *font_str;
160    struct ReEncodeRec *next;
161 } *ReEncodePtr;
162 
163 static struct ReEncodeRec *topReEncodeInfo=NULL;
164 
PSUseReencode(font_str)165 void PSUseReencode(font_str)
166    char *font_str;
167 {
168    if (preDumpSetup && !psUseReencode) {
169       psUseReencode = TRUE;
170       psDictCount += 2;
171    }
172 #ifdef _PRTGIF_USE_ISO_LATIN_1_ALWAYS
173    if (PRTGIF && !psUseReencodeFF8) {
174       psUseReencodeFF8 = TRUE;
175       psDictCount += 2;
176    }
177 #endif /* _PRTGIF_USE_ISO_LATIN_1_ALWAYS */
178    if (font_str != NULL && preDumpSetup && psUseReencode) {
179       struct ReEncodeRec *p_reencode;
180 
181       for (p_reencode=topReEncodeInfo; p_reencode != NULL;
182             p_reencode=p_reencode->next) {
183          if (strcmp(p_reencode->font_str, font_str) == 0) {
184             return;
185          }
186       }
187       p_reencode = (struct ReEncodeRec *)malloc(sizeof(struct ReEncodeRec));
188       if (p_reencode == NULL) FailAllocMessage();
189       p_reencode->font_str = UtilStrDup(font_str);
190       p_reencode->next = topReEncodeInfo;
191       topReEncodeInfo = p_reencode;
192       psDictCount += 1;
193    }
194 }
195 
196 static char *gaszPsShortHand[] = {
197   "GS",   /* "gsave", */
198   "GR",   /* "grestore", */
199   "NP",   /* "newpath", */
200   "CP",   /* "closepath", */
201   "CHP",  /* "charpath", */
202   "CT",   /* "curveto", */
203   "L",    /* "lineto", */
204   "RL",   /* "rlineto", */
205   "M",    /* "moveto", */
206   "RM",   /* "rmoveto", */
207   "S",    /* "stroke", */
208   "F",    /* "fill", */
209   "TR",   /* "translate", */
210   "RO",   /* "rotate", */
211   "SC",   /* "scale", */
212   "MU",   /* "mul", */
213   "DI",   /* "div", */
214   "DU",   /* "dup", */
215   "NE",   /* "neg", */
216   "AD",   /* "add", */
217   "SU",   /* "sub", */
218   "PO",   /* "pop", */
219   "EX",   /* "exch", */
220   "CO",   /* "concat", */
221   "CL",   /* "clip", */
222   "EC",   /* "eoclip", */
223   "EF",   /* "eofill", */
224   "IM",   /* "image", */
225   "IMM",  /* "imagemask", */
226   "ARY",  /* "array", */
227   "SG",   /* "setgray", */
228   "RG",   /* "setrgbcolor", */
229   "SD",   /* "setdash", */
230   "W",    /* "setlinewidth", */
231   "SM",   /* "setmiterlimit", */
232   "SLC",  /* "setlinecap", */
233   "SLJ",  /* "setlinejoin", */
234   "SH",   /* "show", */
235   "FF",   /* "findfont", */
236   "MS",   /* "makefont setfont", */
237   "AR",   /* "arcto 4 {pop} repeat", */
238   "CURP", /* "currentpoint", */
239   "FLAT", /* "flattenpath strokepath clip newpath", */
240   "\tTGSM", /* "tgiforigctm setmatrix", */
241   "\tTGRM", /* "savematrix setmatrix", */
242   NULL
243 };
244 
245 static char *gaszPsLongHand[] = {
246   /* "GS",   */ "gsave",
247   /* "GR",   */ "grestore",
248   /* "NP",   */ "newpath",
249   /* "CP",   */ "closepath",
250   /* "CHP",  */ "charpath",
251   /* "CT",   */ "curveto",
252   /* "L",    */ "lineto",
253   /* "RL",   */ "rlineto",
254   /* "M",    */ "moveto",
255   /* "RM",   */ "rmoveto",
256   /* "S",    */ "stroke",
257   /* "F",    */ "fill",
258   /* "TR",   */ "translate",
259   /* "RO",   */ "rotate",
260   /* "SC",   */ "scale",
261   /* "MU",   */ "mul",
262   /* "DI",   */ "div",
263   /* "DU",   */ "dup",
264   /* "NE",   */ "neg",
265   /* "AD",   */ "add",
266   /* "SU",   */ "sub",
267   /* "PO",   */ "pop",
268   /* "EX",   */ "exch",
269   /* "CO",   */ "concat",
270   /* "CL",   */ "clip",
271   /* "EC",   */ "eoclip",
272   /* "EF",   */ "eofill",
273   /* "IM",   */ "image",
274   /* "IMM",  */ "imagemask",
275   /* "ARY",  */ "array",
276   /* "SG",   */ "setgray",
277   /* "RG",   */ "setrgbcolor",
278   /* "SD",   */ "setdash",
279   /* "W",    */ "setlinewidth",
280   /* "SM",   */ "setmiterlimit",
281   /* "SLC",  */ "setlinecap",
282   /* "SLJ",  */ "setlinejoin",
283   /* "SH",   */ "show",
284   /* "FF",   */ "findfont",
285   /* "MS",   */ "makefont setfont",
286   /* "AR",   */ "arcto 4 {pop} repeat",
287   /* "CURP", */ "currentpoint",
288   /* "FLAT", */ "flattenpath strokepath clip newpath",
289   /* "TGSM", */ "\ttgiforigctm setmatrix",
290   /* "TGRM", */ "\tsavematrix setmatrix",
291   NULL
292 };
293 
PSDontUseShortHand()294 void PSDontUseShortHand()
295 {
296    if (preDumpSetup && psUseShortHand) {
297       char **ppsz=NULL;
298 
299       psUseShortHand = FALSE;
300       psDictCount -= 1;
301       for (ppsz=gaszPsShortHand; *ppsz != NULL; ppsz++) {
302          psDictCount--;
303       }
304       gPsCmd = gaszPsLongHand;
305    }
306 }
307 
PSUseShortHand()308 void PSUseShortHand()
309 {
310    if (preDumpSetup && !psUseShortHand) {
311       char **ppsz=NULL;
312 
313       psUseShortHand = TRUE;
314       psDictCount += 1;
315       for (ppsz=gaszPsShortHand; *ppsz != NULL; ppsz++) {
316          psDictCount++;
317       }
318       gPsCmd = gaszPsShortHand;
319    }
320 }
321 
322 #ifdef _PS_USE_EUC_FONT
PSUseEucFont()323 void PSUseEucFont()
324 {
325    if (preDumpSetup && !psUseEucFont) {
326       psUseEucFont = TRUE;
327       psDictCount += 4;
328    }
329 }
330 #endif /* _PS_USE_EUC_FONT */
331 
332 static
CleanUpReEncodeInfo()333 void CleanUpReEncodeInfo()
334 {
335    struct ReEncodeRec *p_next_reencode;
336 
337    for ( ; topReEncodeInfo != NULL; topReEncodeInfo=p_next_reencode) {
338       p_next_reencode = topReEncodeInfo->next;
339       if (topReEncodeInfo->font_str != NULL) free(topReEncodeInfo->font_str);
340       free(topReEncodeInfo);
341    }
342 }
343 
ResetPSInfo()344 void ResetPSInfo()
345 {
346    psDictCount = DEF_PS_DICT_COUNT;
347    preDumpSetup = TRUE;
348 
349    needsTgifOrigCTM = TRUE;
350 
351    psUsePSAdobe = TRUE;
352 #ifdef INVERT_CTM_BUG
353    UseMinRadius();
354 #else /* ~INVERT_CTM_BUG */
355    psUseMinRadius = FALSE;
356 #endif /* INVERT_CTM_BUG */
357    psUseEllipse = FALSE;
358    psUseArrow = FALSE;
359    psUseArc = FALSE;
360    psUsePattern = FALSE;
361    psUseBWPattern = FALSE;
362    psUseColorImage = FALSE;
363    psUseColorPattern = FALSE;
364    psUseCenterText = FALSE;
365    psUseRightText = FALSE;
366    psUseMiniLines = FALSE;
367    psUseReencode = FALSE;
368    psUseReencodeFF8 = FALSE;
369    psUseShortHand = FALSE;
370 #ifdef _PS_USE_EUC_FONT
371    psUseEucFont = FALSE;
372 #endif /* _PS_USE_EUC_FONT */
373    CleanUpReEncodeInfo();
374 }
375 
DoneResetPSInfo()376 void DoneResetPSInfo()
377 {
378    preDumpSetup = FALSE;
379    CleanUpReEncodeInfo();
380 }
381 
382 static char *psAdobeMacro[] =
383 { "%",
384   "%\tDue to bugs in Transcript, the 'PS-Adobe-' stuff is omitted from line 1",
385   "%",
386   "",
387   NULL
388 };
389 
390 static char *psMinRadiusMacro[] = {
391   "%",
392   "%\tUsing a zero value radius for an ellipse or an arc would result",
393   "%\t\tin a non-invertible CTM matrix which causes problem when this",
394   "%\t\twhen this PostScript is wrapped inside other routines, such as",
395   "%\t\tthe multi.ps package from",
396   "%\t\tftp.ucc.su.oz.au:/pub/ps_printing/multi.  You can overcome such",
397   "%\t\terror by uncommenting the sole line of the procedure below:",
398   "%",
399   "/tgif_min_radius",
400   " {",
401   "%    dup 0.01 lt { pop 0.01 } if",
402   " } bind def",
403   "",
404   NULL
405 };
406 
407 static char *psEllipseMacro[] = {
408   "/tgifellipsedict 6 dict def",
409   "tgifellipsedict /mtrx matrix put",
410   "",
411   "/TGEL % tgifellipse",
412   " { tgifellipsedict begin",
413   "      /yrad exch def",
414   "      /xrad exch def",
415   "      /y exch def",
416   "      /x exch def",
417   "      /savematrix mtrx currentmatrix def",
418   "      x y translate",
419   "      xrad yrad scale",
420   "      0 0 1 0 360 arc",
421   "      savematrix setmatrix",
422   "   end",
423   " } def",
424   "",
425   NULL
426 };
427 
428 static char *psArrowMacro[] = {
429   "/tgifarrowtipdict 8 dict def",
430   "tgifarrowtipdict /mtrx matrix put",
431   "",
432   "/TGAT % tgifarrowtip",
433   " { tgifarrowtipdict begin",
434   "      /dy exch def",
435   "      /dx exch def",
436   "      /h exch def",
437   "      /w exch def",
438   "      /y exch def",
439   "      /x exch def",
440   "      /savematrix mtrx currentmatrix def",
441   "      x y translate",
442   "      dy dx atan rotate",
443   "      0 0 moveto",
444   "      w neg h lineto",
445   "      w neg h neg lineto",
446   "      savematrix setmatrix",
447   "   end",
448   " } def",
449   "",
450   NULL
451 };
452 
453 static char *psArcMacro[] = {
454   "/tgifarcdict 8 dict def",
455   "tgifarcdict /mtrx matrix put",
456   "",
457   "/TGAN % tgifarcn",
458   " { tgifarcdict begin",
459   "      /endangle exch def",
460   "      /startangle exch def",
461   "      /yrad exch def",
462   "      /xrad exch def",
463   "      /y exch def",
464   "      /x exch def",
465   "      /savematrix mtrx currentmatrix def",
466   "      x y translate",
467   "      xrad yrad scale",
468   "      0 0 1 startangle endangle arc",
469   "      savematrix setmatrix",
470   "   end",
471   " } def",
472   "",
473   "/TGAR % tgifarc",
474   " { tgifarcdict begin",
475   "      /endangle exch def",
476   "      /startangle exch def",
477   "      /yrad exch def",
478   "      /xrad exch def",
479   "      /y exch def",
480   "      /x exch def",
481   "      /savematrix mtrx currentmatrix def",
482   "      x y translate",
483   "      xrad yrad scale",
484   "      0 0 1 startangle endangle arcn",
485   "      savematrix setmatrix",
486   "   end",
487   " } def",
488   "",
489   NULL
490 };
491 
492 static char *psBWPatternMacro[] = {
493   "/tgifsetuserscreendict 22 dict def",
494   "tgifsetuserscreendict begin",
495   "   /tempctm matrix def",
496   "   /temprot matrix def",
497   "   /tempscale matrix def",
498   "",
499   "   /concatprocs",
500   "    { /proc2 exch cvlit def",
501   "      /proc1 exch cvlit def",
502   "      /newproc proc1 length proc2 length add array def",
503   "      newproc 0 proc1 putinterval",
504   "      newproc proc1 length proc2 putinterval",
505   "      newproc cvx",
506   "    } def",
507   "   /resmatrix matrix def",
508   "   /findresolution",
509   "    { 72 0 resmatrix defaultmatrix dtransform",
510   "      /yres exch def /xres exch def",
511   "      xres dup mul yres dup mul add sqrt",
512   "    } def",
513   "end",
514   "",
515   "/tgifsetuserscreen",
516   " { tgifsetuserscreendict begin",
517   "      /spotfunction exch def",
518   "      /screenangle exch def",
519   "      /cellsize exch def",
520   "",
521   "      /m tempctm currentmatrix def",
522   "      /rm screenangle temprot rotate def",
523   "      /sm cellsize dup tempscale scale def",
524   "",
525   "      sm rm m m concatmatrix m concatmatrix pop",
526   "",
527   "      1 0 m dtransform /y1 exch def /x1 exch def",
528   "",
529   "      /veclength x1 dup mul y1 dup mul add sqrt def",
530   "      /frequency findresolution veclength div def",
531   "",
532   "      /newscreenangle y1 x1 atan def",
533   "",
534   "      m 2 get m 1 get mul m 0 get m 3 get mul sub 0 gt",
535   "",
536   "      {{neg} /spotfunction load concatprocs",
537   "         /spotfunction exch def",
538   "      } if",
539   "",
540   "      frequency newscreenangle /spotfunction load setscreen",
541   "   end",
542   " } def",
543   "",
544   "/tgifsetpatterndict 18 dict def",
545   "tgifsetpatterndict begin",
546   "   /bitison",
547   "    { /ybit exch def /xbit exch def",
548   "      /bytevalue bstring ybit bwidth mul xbit 8 idiv add get def",
549   "",
550   "      /mask 1 7 xbit 8 mod sub bitshift def",
551   "      bytevalue mask and 0 ne",
552   "    } def",
553   "end",
554   "",
555   "/tgifbitpatternspotfunction",
556   " { tgifsetpatterndict begin",
557   "      /y exch def /x exch def",
558   "",
559   "      /xindex x 1 add 2 div bpside mul cvi def",
560   "      /yindex y 1 add 2 div bpside mul cvi def",
561   "",
562   "      xindex yindex bitison",
563   "       { /onbits onbits 1 add def 1 }",
564   "       { /offbits offbits 1 add def 0 }",
565   "       ifelse",
566   "   end",
567   " } def",
568   "",
569   "/tgifsetpattern",
570   " { tgifsetpatterndict begin",
571   "      /cellsz exch def",
572   "      /angle exch def",
573   "      /bwidth exch def",
574   "      /bpside exch def",
575   "      /bstring exch def",
576   "",
577   "      /onbits 0 def /offbits 0 def",
578   "      cellsz angle /tgifbitpatternspotfunction load tgifsetuserscreen",
579   "      {} settransfer",
580   "      offbits offbits onbits add div setgray",
581   "   end",
582   " } def",
583   "",
584   NULL
585 };
586 
587 static char *psColorImageMacro[] = {
588   "/tgifxpmdict 4 dict def",
589   "/tgifbwpicstr 1 string def",
590   "/tgifcolorpicstr 3 string def",
591   "",
592   "/tgifsetpixels { tgifxpmdict begin /pixels exch def end } def",
593   "",
594   "/tgifsetpix { tgifxpmdict begin pixels 3 1 roll putinterval end } def",
595   "",
596   "/tgifsetppmtruetranspix",
597   " { tgifxpmdict begin",
598   "      3 array /transpixels exch def",
599   "      transpixels 2 3 -1 roll put",
600   "      transpixels 1 3 -1 roll put",
601   "      transpixels 0 3 -1 roll put",
602   "      /curpix 3 array def",
603   "   end",
604   " } def",
605   "",
606   "/tgifcolorspot",
607   " { tgifxpmdict begin",
608   "      /index exch def",
609   "      pixels index 3 mul 3 getinterval aload pop",
610   "      255 mul cvi tgifcolorpicstr 2 3 -1 roll put",
611   "      255 mul cvi tgifcolorpicstr 1 3 -1 roll put",
612   "      255 mul cvi tgifcolorpicstr 0 3 -1 roll put",
613   "      tgifcolorpicstr",
614   "   end",
615   " } def",
616   "",
617   "/tgifcolordict 4 dict def",
618   "",
619   "/colorimage where",
620   " { pop }",
621   " { /colorimage",
622   "   { tgifcolordict begin",
623   "        pop pop pop pop pop",
624   "        /ih exch def",
625   "        /iw exch def",
626   "        /x 0 def",
627   "        /y 0 def",
628   "        1 1 ih",
629   "         { pop 1 1 iw",
630   "            { pop",
631   "              3 { currentfile tgifbwpicstr readhexstring pop 0 get 255 div } repeat setrgbcolor",
632   "              newpath x y moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto",
633   "              closepath fill",
634   "              /x x 1 add def",
635   "            } for",
636   "           /y y 1 add def",
637   "           /x 0 def",
638   "         } for",
639   "     end",
640   "   } def",
641   " } ifelse",
642   "",
643   "/tgiftranscolorspot",
644   " { tgifxpmdict begin",
645   "      /index exch def",
646   "      pixels index 3 mul 3 getinterval aload pop",
647   "      dup 0 lt { pop pop pop false } { setrgbcolor true } ifelse",
648   "   end",
649   " } def",
650   "",
651   "/tgiftranscolorimage",
652   " { tgifcolordict begin",
653   "      pop pop pop pop pop",
654   "      /ih exch def",
655   "      /iw exch def",
656   "      /x 0 def",
657   "      /y 0 def",
658   "      1 1 ih",
659   "       { pop 1 1 iw",
660   "          { pop currentfile",
661   "            tgifbwpicstr readhexstring pop 0 get tgiftranscolorspot",
662   "            { newpath x y moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto",
663   "              closepath fill",
664   "            }",
665   "            if",
666   "            /x x 1 add def",
667   "          } for",
668   "         /y y 1 add def",
669   "         /x 0 def",
670   "       } for",
671   "   end",
672   " } def",
673   "",
674   "/tgiftransppmtruecolorspot",
675   " { tgifxpmdict begin",
676   "      /count 0 def",
677   "      curpix 2 3 -1 roll put",
678   "      curpix 1 3 -1 roll put",
679   "      curpix 0 3 -1 roll put",
680   "      curpix 0 get transpixels 0 get ne { /count count 1 add def } if",
681   "      curpix 1 get transpixels 1 get ne { /count count 1 add def } if",
682   "      curpix 2 get transpixels 2 get ne { /count count 1 add def } if",
683   "      count 0 eq { false } { curpix 0 get 255 div curpix 1 get 255 div curpix 2 get 255 div setrgbcolor true } ifelse",
684   "   end",
685   " } def",
686   "",
687   "/tgiftransppmtruecolorimage",
688   " { tgifcolordict begin",
689   "      pop pop pop pop pop",
690   "      /ih exch def",
691   "      /iw exch def",
692   "      /x 0 def",
693   "      /y 0 def",
694   "      1 1 ih",
695   "       { pop 1 1 iw",
696   "          { pop",
697   "            3 { currentfile tgifbwpicstr readhexstring pop 0 get } repeat tgiftransppmtruecolorspot",
698   "            { newpath x y moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto",
699   "              closepath fill",
700   "            }",
701   "            if",
702   "            /x x 1 add def",
703   "          } for",
704   "         /y y 1 add def",
705   "         /x 0 def",
706   "       } for",
707   "   end",
708   " } def",
709   "",
710   NULL
711 };
712 
713 static char *psColorPatternMacro[] = {
714   "/tgifpatdict 12 dict def",
715   "",
716   "/tgifpatbyte",
717   " { currentdict /retstr get exch",
718   "   bytesperrow mul",
719   "   pat i cellh mod bytesperrow mul bytesperrow getinterval putinterval",
720   " } def",
721   "",
722   "/tgifpatproc",
723   " { 0 1 cells_wd 1 sub {tgifpatbyte} for retstr",
724   "   /i i 1 add def",
725   " } def",
726   "",
727   "/TGPF % tgifpatfill",
728   " { tgifpatdict begin",
729   "      /h exch def",
730   "      /w exch def",
731   "      /lty exch def",
732   "      /ltx exch def",
733   "      /cellh exch def",
734   "      /cellw exch def",
735   "      /pat exch def",
736   "",
737   "      /cells_wd w cellw div cvi def",
738   "      /bytesperrow cellw 8 div ceiling cvi def",
739   "      /retstr cells_wd bytesperrow mul string def",
740   "      /i 0 def",
741   "",
742   "      tgiforigctm setmatrix",
743   "      ltx lty translate",
744   "      w h true [1 0 0 1 0 0] {tgifpatproc} imagemask",
745   "      ltx neg lty neg translate",
746   "   end",
747   " } def",
748   "",
749   NULL
750 };
751 
752 /*
753  * No longer needed.
754  * Now psDynamicPrintPatternDef() generates these from pixmap data.
755  *
756  * static char *psPatternMacro[] = {
757  *   "/pat3 <8000000008000000> def",
758  *   "/pat4 <8800000022000000> def",
759  *   "/pat5 <8800220088002200> def",
760  *   "/pat6 <8822882288228822> def",
761  *   "/pat7 <aa55aa55aa55aa55> def",
762  *   "/pat8 <77dd77dd77dd77dd> def",
763  *   "/pat9 <77ffddff77ffddff> def",
764  *   "/pat10 <77ffffffddffffff> def",
765  *   "/pat11 <7ffffffff7ffffff> def",
766  *   "/pat12 <8040200002040800> def",
767  *   "/pat13 <40a00000040a0000> def",
768  *   "/pat14 <ff888888ff888888> def",
769  *   "/pat15 <ff808080ff080808> def",
770  *   "/pat16 <f87422478f172271> def",
771  *   "/pat17 <038448300c020101> def",
772  *   "/pat18 <081c22c180010204> def",
773  *   "/pat19 <8080413e080814e3> def",
774  *   "/pat20 <8040201008040201> def",
775  *   "/pat21 <8844221188442211> def",
776  *   "/pat22 <77bbddee77bbddee> def",
777  *   "/pat23 <c1e070381c0e0783> def",
778  *   "/pat24 <7fbfdfeff7fbfdfe> def",
779  *   "/pat25 <3e1f8fc7e3f1f87c> def",
780  *   "/pat26 <0102040810204080> def",
781  *   "/pat27 <1122448811224488> def",
782  *   "/pat28 <eeddbb77eeddbb77> def",
783  *   "/pat29 <83070e1c3870e0c1> def",
784  *   "/pat30 <fefdfbf7efdfbf7f> def",
785  *   "/pat31 <7cf8f1e3c78f1f3e> def",
786  *   "",
787  *   NULL
788  * };
789  */
790 
psDynamicPrintPatternDef(FP,index)791 void psDynamicPrintPatternDef(FP, index)
792    FILE *FP;
793    int index;
794 {
795    int b=0, numbytes=0, need_to_free=FALSE;
796    unsigned char *bytes=NULL;
797 
798    bytes = (unsigned char *)GetPatternBytes(index, &numbytes, &need_to_free);
799    fprintf(FP, "/pat%d <", index);
800    for (b=0; b < numbytes; b++) {
801       fprintf(FP, "%02hhx", ByteReverse(bytes[b]));
802    }
803    fprintf(FP, "> def\n");
804    if (need_to_free) UtilFree((char*)bytes);
805 }
806 
807 static char *psCenterTextMacro[] = {
808   "/TGCTX { dup stringwidth pop 2 div neg 0 rmoveto } def",
809   "",
810   NULL
811 };
812 
813 static char *psMiniLinesMacro[] = {
814   "/TGMAX",
815   " { exch dup 3 1 roll exch dup 3 1 roll gt { pop } { exch pop } ifelse",
816   " } def",
817   "/TGMIN",
818   " { exch dup 3 1 roll exch dup 3 1 roll lt { pop } { exch pop } ifelse",
819   " } def",
820   "/TGSW { stringwidth pop } def",
821   "/tgifstrw 0 def",
822   "",
823   NULL
824 };
825 
826 static char *psRightTextMacro[] = {
827   "/TGRTX { dup stringwidth pop neg 0 rmoveto } def",
828   "",
829   NULL
830 };
831 
832 static char *psReencodeMacro[] = {
833   "/tgifreencsmalldict 12 dict def",
834   "/tgifReEncodeSmall",
835   " { tgifreencsmalldict begin",
836   "      /newcodesandnames exch def",
837   "      /newfontname exch def",
838   "      /basefontname exch def",
839   "",
840   "      /basefontdict basefontname findfont def",
841   "      /newfont basefontdict maxlength dict def",
842   "",
843   "      basefontdict",
844   "      { exch dup /FID ne",
845 #ifdef GS_REENCODE_BUG
846   "        1 index /UniqueID ne and",
847 #endif
848   "         { dup /Encoding eq",
849   "            { exch dup length array copy newfont 3 1 roll put }",
850   "            { exch newfont 3 1 roll put }",
851   "            ifelse",
852   "         }",
853   "         { pop pop }",
854   "         ifelse",
855   "      }",
856   "      forall",
857   "",
858   "      newfont /FontName newfontname put",
859   "      newcodesandnames aload pop",
860   "",
861   "      newcodesandnames length 2 idiv",
862   "      { newfont /Encoding get 3 1 roll put}",
863   "      repeat",
864   "",
865   "      newfontname newfont definefont pop",
866   "   end",
867   " } def",
868   "",
869   NULL
870 };
871 
872 #ifdef _PRTGIF_USE_ISO_LATIN_1_ALWAYS
873 static char *psReEncodeFF8Macro[] = {
874   "/TGFF8",
875   " { FontDirectory 1 index known",
876   "   { pop findfont exch pop }",
877   "   { 1 index 4 1 roll tgifReEncodeSmall findfont } ifelse",
878   " } bind def",
879   "",
880   NULL
881 };
882 #endif /* _PRTGIF_USE_ISO_LATIN_1_ALWAYS */
883 
884 static char *psShortHandMacro[] = {
885   "/bd { bind def } bind def",
886   "",
887   NULL
888 };
889 
890 #ifdef _PS_USE_EUC_FONT
891 static char *psEucFontMacro[] = {
892   "%%Title: eucfont.ps",
893   "% old eucfont.ps(OCFeucfont) and new eucfont.ps(CIDeucfont) were combined.",
894   "%  1996-09, kawamata@sra.co.jp",
895   "% Sample Usage:",
896   "%   Operands are only font names permitted. Don't put fontdict itself.",
897   "% /Courier-Ryumin /Courier /Ryumin-Light-EUC-V eucfont",
898   "",
899   "%%Title: CIDeucfont.ps",
900   "%%Creator: yohtaki@cis.ibaraki.ac.jp",
901   "%%CreationDate: 1996-9-29",
902   "%%EndComments",
903   "%",
904   "% <newfont> <asciifont> <kanjifont> CIDeucfont",
905   "/CIDeucfont {",
906   "dup findfont /WMode get 1 eq 4 1 roll % push direction info.",
907   "12 dict begin",
908   "  /CIDInit /ProcSet findresource begin",
909   "  exch [ 3 1 roll ] beginrearrangedfont",
910   "      3 -1 roll {   % pop direction info",
911   "         /WMode 1 def	% vertical font",
912 #ifdef _VERT_FONT_OFFSET_POINT_4
913   "         0 beginusematrix [ 0 1 -1 0 0 0.4 ] endusematrix",
914 #else /* ~_VERT_FONT_OFFSET_POINT_4 */
915   "         0 beginusematrix [ 0 1 -1 0 0 0.3 ] endusematrix",
916 #endif /* _VERT_FONT_OFFSET_POINT_4 */
917   "      } if",
918   "      1 usefont",
919   "      1 beginbfrange",
920   "         <00> <7F> <00>",
921   "       endbfrange",
922   "     endrearrangedfont",
923   "  end",
924   "end",
925   "} def",
926   "",
927   "%%Title: OCFeucfont.ps",
928   "%%Creator: shikida@cs.titech.ac.jp, ueno@cs.titech.ac.jp",
929   "%%CreationDate: 1991-2-27",
930   "%%EndComments",
931   "% <font> OCFcopyfont <font>",
932   "/OCFcopyfont {",
933   "    dup maxlength 1 add dict begin",
934   "    {",
935   "	1 index /FID ne 2 index /UniqueID ne and",
936   "	{def} {pop pop} ifelse",
937   "    } forall",
938   "    currentdict",
939   "    end",
940   "} bind def",
941   "% <newfont> <asciifont> <kanjifont> OCFeucfont",
942   "/OCFeucfont {",
943   "      12 dict begin",
944   "	dup type /nametype eq { findfont } if",
945   "	dup /WMode known {",
946   "	    dup /WMode get /WMode exch def",
947   "	    WMode 1 eq {",
948 #ifdef _VERT_FONT_OFFSET_POINT_4
949   "		[0.0 1.0 -1.0 0.0 0.0 0.40] makefont",
950 #else /* ~_VERT_FONT_OFFSET_POINT_4 */
951   "		[0.0 1.0 -1.0 0.0 0.0 0.30] makefont",
952 #endif /* _VERT_FONT_OFFSET_POINT_4 */
953   "	    } if",
954   "	} if",
955   "	OCFcopyfont dup begin",
956   "	    /Encoding Encoding",
957   "	    FMapType dup 2 eq {",
958   "		pop 128 128",
959   "	    } { 5 eq {",
960   "		256 256",
961   "	    } {",
962   "		/compositefont errordict /invalidfont get exec",
963   "	    } ifelse",
964   "	    } ifelse",
965   "	    getinterval def",
966   "	end",
967   "	/kanjifont exch definefont",
968   "	exch",
969   "",
970   "	dup type /nametype eq { findfont } if",
971   "	exch",
972   "",
973   "	/FDepVector [ 4 2 roll ] def",
974   "	/FontType 0 def",
975   "	/FMapType 4 def",
976   "	/FontMatrix matrix def",
977   "	/Encoding [ 0 1 ] def",
978   "	/FontBBox {0 0 0 0} def",
979   "	dup /FontName exch def",
980   "	currentdict",
981   "    end",
982   "    definefont pop",
983   "} def",
984   "",
985   "% <newfont> <asciifont> <kanjifont> eucfont",
986   "/eucfont {",
987   "	dup findfont",
988   "	/FMapType get 9 eq",
989   "		{ CIDeucfont}",
990   "		{ OCFeucfont} ifelse",
991   "} def",
992   "",
993   NULL
994 };
995 #endif /* _PS_USE_EUC_FONT */
996 
DumpPSMacro(FP)997 void DumpPSMacro(FP)
998    FILE *FP;
999 {
1000    register int i;
1001 
1002    fprintf(FP, "\n");
1003    if (!psUsePSAdobe) {
1004       for (i=0; psAdobeMacro[i] != NULL; i++) {
1005          fprintf(FP, "%s\n", psAdobeMacro[i]);
1006       }
1007    }
1008 
1009    fprintf(FP, "/tgifdict %1d dict def\n", psDictCount);
1010    fprintf(FP, "tgifdict begin\n");
1011    fprintf(FP, "\n");
1012 
1013    if (psUseMinRadius) {
1014       for (i=0; psMinRadiusMacro[i] != NULL; i++) {
1015          fprintf(FP, "%s\n", psMinRadiusMacro[i]);
1016       }
1017    }
1018    if (psUseEllipse) {
1019       for (i=0; psEllipseMacro[i] != NULL; i++) {
1020          fprintf(FP, "%s\n", psEllipseMacro[i]);
1021       }
1022    }
1023    if (psUseArrow) {
1024       for (i=0; psArrowMacro[i] != NULL; i++) {
1025          fprintf(FP, "%s\n", psArrowMacro[i]);
1026       }
1027    }
1028    if (psUseArc) {
1029       for (i=0; psArcMacro[i] != NULL; i++) {
1030          fprintf(FP, "%s\n", psArcMacro[i]);
1031       }
1032    }
1033    if (psUseBWPattern) {
1034       for (i=0; psBWPatternMacro[i] != NULL; i++) {
1035          fprintf(FP, "%s\n", psBWPatternMacro[i]);
1036       }
1037    }
1038    if (psUseColorImage) {
1039       for (i=0; psColorImageMacro[i] != NULL; i++) {
1040          fprintf(FP, "%s\n", psColorImageMacro[i]);
1041       }
1042    }
1043    if (psUseColorPattern) {
1044       for (i=0; psColorPatternMacro[i] != NULL; i++) {
1045          fprintf(FP, "%s\n", psColorPatternMacro[i]);
1046       }
1047    }
1048    if (psUsePattern) {
1049       /*
1050        * for (i=0; psPatternMacro[i] != NULL; i++) {
1051        *    fprintf(FP, "%s\n", psPatternMacro[i]);
1052        * }
1053        */
1054       for (i=3; i < 32; i++) {
1055          psDynamicPrintPatternDef(FP, i);
1056       }
1057       fprintf(FP, "\n");
1058    }
1059    if (psUseCenterText) {
1060       for (i=0; psCenterTextMacro[i] != NULL; i++) {
1061          fprintf(FP, "%s\n", psCenterTextMacro[i]);
1062       }
1063    }
1064    if (psUseRightText) {
1065       for (i=0; psRightTextMacro[i] != NULL; i++) {
1066          fprintf(FP, "%s\n", psRightTextMacro[i]);
1067       }
1068    }
1069    if (psUseMiniLines) {
1070       for (i=0; psMiniLinesMacro[i] != NULL; i++) {
1071          fprintf(FP, "%s\n", psMiniLinesMacro[i]);
1072       }
1073    }
1074 #ifdef _PRTGIF_USE_ISO_LATIN_1_ALWAYS
1075    if (PRTGIF && psUseReencodeFF8) {
1076       for (i=0; psReEncodeFF8Macro[i] != NULL; i++) {
1077          fprintf(FP, "%s\n", psReEncodeFF8Macro[i]);
1078       }
1079       DumpReEncodeVector(FP, "latin1", ".vec", NULL);
1080    }
1081 #endif /* _PRTGIF_USE_ISO_LATIN_1_ALWAYS */
1082    if (psUseReencode) {
1083       for (i=0; psReencodeMacro[i] != NULL; i++) {
1084          fprintf(FP, "%s\n", psReencodeMacro[i]);
1085       }
1086    }
1087    if (psUseShortHand) {
1088       for (i=0; psShortHandMacro[i] != NULL; i++) {
1089          fprintf(FP, "%s\n", psShortHandMacro[i]);
1090       }
1091       for (i=0; gaszPsLongHand[i] != NULL; i++) {
1092          if (*gaszPsLongHand[i] == '\t') {
1093             fprintf(FP, "/%s { %s } def\n", &(gaszPsShortHand[i])[1],
1094                   &(gaszPsLongHand[i])[1]);
1095          } else {
1096             fprintf(FP, "/%s { %s } bd\n", gaszPsShortHand[i],
1097                   gaszPsLongHand[i]);
1098          }
1099       }
1100       fprintf(FP, "\n");
1101       gPsCmd = gaszPsShortHand;
1102    } else {
1103       gPsCmd = gaszPsLongHand;
1104    }
1105 #ifdef _PS_USE_EUC_FONT
1106    if (psUseEucFont) {
1107       for (i=0; psEucFontMacro[i] != NULL; i++) {
1108          fprintf(FP, "%s\n", psEucFontMacro[i]);
1109       }
1110    }
1111 #endif /* _PS_USE_EUC_FONT */
1112 }
1113 
ParsePsAdobeString(buf,use_ps_adobe_string,adobe_str,epsf_str)1114 int ParsePsAdobeString(buf, use_ps_adobe_string, adobe_str, epsf_str)
1115    char *buf, *adobe_str, *epsf_str;
1116    int *use_ps_adobe_string;
1117 {
1118    if (UtilStrICmp("false", buf) == 0 || UtilStrICmp("no", buf) == 0) {
1119       *use_ps_adobe_string = FALSE;
1120    } else if (UtilStrICmp("true", buf) == 0 || UtilStrICmp("yes", buf) == 0) {
1121       *use_ps_adobe_string = TRUE;
1122    } else if (*buf >= '0' && *buf <= '9') {
1123       char *c_ptr=buf, *c_ptr1=NULL;
1124 
1125       *use_ps_adobe_string = TRUE;
1126       for (c_ptr1=c_ptr; *c_ptr1 != '\0'; c_ptr1++) {
1127          if (*c_ptr1 == '/') {
1128             *c_ptr1 = ' ';
1129             break;
1130          }
1131       }
1132       sscanf(c_ptr, "%s", adobe_str);
1133       c_ptr = &c_ptr[strlen(adobe_str)];
1134       switch (*c_ptr) {
1135       case '\0': break;
1136       case ' ':
1137          c_ptr++;
1138          if (*c_ptr >= '0' && *c_ptr <= '9') {
1139             sscanf(c_ptr, "%s", epsf_str);
1140          } else {
1141             return FALSE;
1142          }
1143          break;
1144       default: return FALSE;
1145       }
1146    } else {
1147       return FALSE;
1148    }
1149    return TRUE;
1150 }
1151 
CleanUpPS()1152 void CleanUpPS()
1153 {
1154 }
1155 
InitPS()1156 void InitPS()
1157 {
1158 }
1159 
1160